您的位置:首页 > 其它

动态规划入门 DP基础

2016-04-21 18:52 549 查看
    1,  http://poj.org/problem?id=1163
#include<iostream>
using namespace std;
int main()
{
int a[101][101],i,j,d[101][101];
int n;
while(cin>>n&&n)
{
for(i=1;i<=n;i++)
for(j=1;j<=i;j++)
cin>>a[i][j];
for(j=1;j<=n;j++) d
[j]=a
[j];
for(i=n-1;i>=1;i--)
for(j=1;j<=i;j++)
if(d[i+1][j]>d[i+1][j+1])
d[i][j]=a[i][j]+d[i+1][j];
else d[i][j]=a[i][j]+d[i+1][j+1];
cout<<d[1][1]<<endl;
}
return 0;
}#include<iostream>
using namespace std;
int main()
{
int a[101][101],i,j;
int n;
while(cin>>n&&n)
{
for(i=1;i<=n;i++)
for(j=1;j<=i;j++)
cin>>a[i][j];
for(i=n-1;i>=1;i--)
for(j=1;j<=i;j++)
if(a[i+1][j]>a[i+1][j+1])
a[i][j]=a[i][j]+a[i+1][j];
else a[i][j]=a[i][j]+a[i+1][j+1];
cout<<a[1][1]<<endl;
}
return 0;
}#include<iostream>//记忆化搜索
using namespace std;
int a[100][100];int d[100][100]; int n;
int max(int a,int b)
{
if(a>b)return a;
else return b;
}
int solve(int i,int j)
{
if(d[i][j]>=0)return d[i][j];
return d[i][j]=a[i][j]+(i==n?0:max(solve(i+1,j),solve(i+1,j+1)));
}
int main()
{

while(cin>>n&&n)
{
memset(d,-1,sizeof(d));
for(int i=0;i<n;i++)
for(int j=0;j<=i;j++)
cin>>a[i][j];
cout<<solve(0,0)<<endl;

}
return 0;
}

方法二比较快~~,很明显。。http://vjudge.net/contest/view.action?cid=50286#problem/A Robberies解题思路:将此问题看成是01背包问题,其中将几个银行的总钱数看作背包容量,dp[]是能得到的最大钱数,将成功偷盗的几率看成是价值 
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<vector>
#include<cmath>
#include<stdlib.h>
#include<iomanip>
#include<list>
#include<deque>
#include<map>
#include <stdio.h>
#include <queue>

#define maxn 10000+5
#define ull unsigned long long
#define ll long long
#define reP(i,n) for(i=1;i<=n;i++)
#define rep(i,n) for(i=0;i<n;i++)
#define cle(a) memset(a,0,sizeof(a))
#define mod 90001
#define PI 3.141592657

const ull inf = 1LL << 61;
const double eps=1e-5;

using namespace std;

bool cmp(int a,int b){
return a>b;
}
float p,pj,q,qj;int n,mj;
float dp[5000];
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int t;
cin>>t;
int vol[105];float val[105];
while(t--)
{
cle(dp);cle(val);cle(vol);
cin>>p>>n;int v=0;float a;
for(int i=1;i<=n;i++)
{
cin>>vol[i]>>a;
v+=vol[i];val[i]=1-a;
}
dp[0]=1;
for(int i=1;i<=n;i++)
for(int j=v;j>=vol[i];j--)
dp[j]=max(dp[j],dp[j-vol[i]]*val[i]);
int i;
for(i = v; i>=0;i--)
{
if(dp[i] >=1-p)
{
break;
}
}
cout<<i<<endl;
}
return 0;
}
http://vjudge.net/contest/view.action?cid=50286#problem/B最大报销额还是01背包问题,这里面有特殊,就是cost和weight(价值)是相同的,V是可以报销的钱数

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<vector>
#include<cmath>
#include<stdlib.h>
#include<iomanip>
#include<list>
#include<deque>
#include<map>
#include <stdio.h>
#include <queue>

#define maxn 10000+5
#define ull unsigned long long
#define ll long long
#define reP(i,n) for(i=1;i<=n;i++)
#define rep(i,n) for(i=0;i<n;i++)
#define cle(a) memset(a,0,sizeof(a))
#define mod 90001
#define PI 3.141592657

const ull inf = 1LL << 61;
const double eps=1e-5;

using namespace std;

bool cmp(int a,int b){
return a>b;
}
double q;int n;int dp[3000005],mark,f[32],p;
int num;char s,c; float a,suma,sumb,sumc;
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
while(cin>>q>>n)
{
if(n==0)break;
p=0;
cle(dp);cle(f);
for(int k=0;k<n;k++)
{   suma=0.0;sumb=0.0;sumc=0.0;mark=0;
cin>>num;
for(int i=0;i<num;i++)
{
cin>>s>>c>>a; ///char c[6];
if(s=='A')suma+=a;
else if(s=='B')sumb+=a;
else if(s=='C')sumc+=a;
else {mark=1;break;}
}
if(mark||(suma+sumb+sumc)>1000||suma>600||sumb>600||sumc>600)continue;
f[p++]=100*(suma+sumb+sumc);
}
for(int i=0;i<p;i++)
for(int j=q*100;j>=f[i];j--)
{
dp[j]=max(dp[j],dp[j-f[i]]+f[i]);
}
int t=q*100;
cout<<fixed<<setprecision(2)<<dp[t]*0.01<<endl;
}
return 0;
}


http://vjudge.net/contest/view.action?cid=50286#problem/DMax Sum
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<vector>
#include<cmath>
#include<stdlib.h>
#include<iomanip>
#include<list>
#include<deque>
#include<map>
#include <stdio.h>
#include <queue>

#define maxn 10000+5
#define ull unsigned long long
#define ll long long
#define reP(i,n) for(i=1;i<=n;i++)
#define rep(i,n) for(i=0;i<n;i++)
#define cle(a) memset(a,0,sizeof(a))
#define mod 90001
#define PI 3.141592657

const ull inf = 1LL << 61;
const double eps=1e-5;

using namespace std;

bool cmp(int a,int b){
return a>b;
}
int a[100005];
int sum[100005];
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int t,n;cin>>t;
for(int k=1;k<=t;k++)
{ cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
sum[1]=a[1];int x=1,start=1,end=1;int max1=a[1];
for(int i=2;i<=n;i++)
{
if(a[i]+sum[i-1]<a[i])
{
sum[i]=a[i];x=i;
}
else sum[i]=sum[i-1]+a[i];
if(sum[i]>max1)
{
max1=sum[i];start=x;end=i;
}
}
cout<<"Case "<<k<<":"<<endl;
cout<<max1<<" "<<start<<" "<<end<<endl;
if(k!=t)cout<<endl;
}
return 0;
}
这道题的状态转移方程为  sum[i]=max(sum[i-1]+a[i],a[i])    值得注意的是怎么保存开始和结束点的位置
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: