标签:
1 1000 5 800 2 400 5 300 5 400 3 200 2
3900
此题属于01背包问题,核心为01背包的的状态转换方程 就此题来说设p[i]为物体的钱数,z[i]为物体的重要度,另设一数组dp[i],n为所持有的总钱数,m为要购买物品的总件数 则此题的转换方程为 dp[n]=max(dp[i],dp[n-p[i]]+z[i]*p[i]) 解释一下:当比较每一组数据时背包容量都从n开始变化,到这组数据的价钱数处结束,拿第一组数据来说,价格为800,重要度为2,则背包容量依次减小,到800处停下,此时数组dp[800]到dp[1000]中已经被赋上初值了,然后比较第二组数据若第二组数据的结果比第一组数据大则用大的值覆盖前边小的值,以此类推 当然当后边物品钱数和不超过n,则取和以求到最大值
附上AC代码
#include<stdio.h> #include<string.h> int main() { int dp[50000]; //注意这个表示价钱的数组不能开的太小 int N,n,m,j,i; int w[30],p[30]; scanf("%d",&N); while(N--) { memset(dp,0,sizeof(dp)); scanf("%d %d",&n,&m); for(i=0;i<m;i++) scanf("%d%d",&w[i],&p[i]); for(i=0;i<m;i++) { for(j=n;j>=w[i];j--) { if(dp[j]<dp[j-w[i]]+p[i]*w[i]) //此题的核心 状态转换方程 dp[j]=dp[j-w[i]]+p[i]*w[i]; } } printf("%d\n",dp[n]); } return 0; }
标签:
原文地址:http://www.cnblogs.com/tonghao/p/4424755.html