动态规划典型入门例题
3714:点菜问题
总时间限制:
1000ms
内存限制:
65536kB
描述
北大网络实验室经常有活动需要叫外买,但是每次叫外买的报销经费的总额最大为C元,有N种菜可以点
,经过长时间的点菜,网络实验室对于每种菜i都有一个量化的评价分数(表示这个菜可口程度),为Vi,每种菜的价格为Pi, 问如何选择各种菜,使得在报销额度范围内能使点到的菜的总评价分数最大?
注意:由于需要营养多样化,每种菜只能点一次。
输入
输入的第一行有两个整数C(1 <= C <= 1000)和N(1 <= N <= 100),C代表总共能够报销的额度,N>代表能点菜的数目。接下来的N行每行包括两个在1到100之间(包括1和100)的的整数,分别表示菜的>价格和菜的评价分数。
输出
输出只包括一行,这一行只包含一个整数,表示在报销额度范围内,所点的菜得到的最大评价分数。
样例输入
90 4
20 25
30 20
40 50
10 18
40 2
25 30
10 8
样例输出
95
38
递推关系
dp[i][j]=max(dp[i-1][j],dp[i-1][j-w[i]]+v[i]);
取和不取第i个菜两种情况取最大值,dp[i-1][j]表示不取第i种,那么从i-1种菜取放入j容量背包。dp[i-1][j-w[i]]+v[i]表示取第i种菜,那么背包容量j-w[i],但是价值增加w[i].
代码:
#include<iostream>
#include<algorithm>
#include<string.h>
using namespace std;
int w[1001];
int v[1001];
int dp[1001][1001];
int main()
{
int c,n;
while(cin>>c>>n)
{
memset(dp,0,sizeof(dp));
for(int i=1;i<=n;i++)
cin>>w[i]>>v[i];
for(int i=1;i<=n;i++)
for(int j=0;j<=c;j++)
{
if(j<w[i]) //背包容量不够第i种菜,则一定是不取
dp[i][j]=dp[i-1][j];
else
{
dp[i][j]=max(dp[i-1][j],dp[i-1][j-w[i]]+v[i]);
/*取和不取第i个菜两种情况取最大值,dp[i-1][j]表示不取第i种,那么从i-1种菜取放入j容量背包。dp[i-1][j-w[i]]+v[i]表示取第i种菜,那么背包容量j-w[i],但是价值增加w[i].*/
}
}
cout<<dp[n][c]<<endl;
}
return 0;
}
空间优化
#include<iostream>
#include<algorithm>
#include<string.h>
using namespace std;
int w[1001];
int v[1001];
int dp[1001];
int main()
{
int c,n;
while(cin>>c>>n)
{
memset(dp,0,sizeof(dp));
for(int i=1;i<=n;i++)
cin>>w[i]>>v[i];
for(int i=1;i<=n;i++)
for(int j=c;j>=w[i];j--)
dp[j]=max(dp[j],dp[j-w[i]]+v[i]);
cout<<dp[c]<<endl;
}
return 0;
}
3727:摘花生
总时间限制:
1000ms
内存限制:
65536kB
描述
Hello Kitty 想摘点花生送给她喜欢的米老鼠。她来到一片有网格状道路的矩形花生地(如下图),从西北角进去,东南角出来。地里每个道路的交叉点上都有种着一株花生苗,上面有若干颗花生,经过一株花生苗就能摘走该它上面所有的花生。Hello Kitty只能向东或向南走,不能向西或向北走。问Hello Kitty 最多能够摘到多少颗花生。
输入
第一行是一个整数T,代表一共有多少组数据。1<=T <= 100
接下来是T组数据。
每组数据的第一行是两个整数,分别代表花生苗的行数R和列数 C ( 1<= R,C <=100)
每组数据的接下来R行数据,从北向南依次描述每行花生苗的情况。每行数据有 C 个整数,按从西向东的顺序描述了该行每株花生苗上的花生数目 M ( 0<= M <= 1000)。
输出
对每组输入数据,输出一行,内容为Hello Kitty能摘到得最多的花生颗数。
样例输入
2
2 2
1 1
3 4
2 3
2 3 4
1 6 5
样例输出
8
16
#include<iostream>
#include<string.h>
#include<algorithm>
using namespace std;
int dp[102][102];
int main()
{
int r,c;
int t;
cin>>t;
while(t--){
cin>>r>>c;
memset(dp,0,sizeof(dp));
int w[r+2][c+2];
for(int i=1;i<=r;i++)
for(int j=1;j<=c;j++)
cin>>w[i][j];
dp[1][1]=w[1][1];
for(int i=2;i<=r;i++)
dp[i][1]=w[i][1]+dp[i-1][1];
for(int i=2;i<=c;i++)
dp[1][i]=w[1][i]+dp[1][i-1];
for(int i=2;i<=r;i++)
for(int j=2;j<=c;j++)
dp[i][j]=max(dp[i-1][j]+w[i][j],dp[i][j-1]+w[i][j]);
cout<<dp[r][c]<<endl;
}
return 0;
}