最简单的DP问题3——hdu2191

来源:互联网 发布:知乎日报 rss源 编辑:程序博客网 时间:2024/06/04 18:37

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2191

中文题。

多重背包,并且用2进制来优化。
详情看注释,重点部分写的很详细了

#include<stdio.h>#define max(a,b) ((a)>(b))?(a):(b)int t;int n, m;int value[105], weight[105], num[105];int dp[105];int main(){    int i,j,k;    scanf("%d", &t);    while(t--)    {        for(i = 0 ; i < 105 ; i++)            dp[i] = 0;             scanf("%d %d", &n, &m);        for(i=1; i<=m; ++i)//每输入一种处理一次          {            scanf("%d %d %d", &value[i], &weight[i], &num[i]);               //如果这种粮食总价格大于等于预算相当于无限取用              //这种情况下你把钱花光的最好结果也是刚好买完这种粮食              //故使用完全背包            if(num[i] * value[i] >= n)            {                for(j = value[i] ; j <= n ; j++)                    dp[j] = max(dp[j],dp[j-value[i]]+weight[i]);            }            else//不然使用01背包法            {            //二进制优化:一个整数一定可以化为二进制+余数            //举个例子 16 == 1+2+4+8   +1            //循环算的话需要16次,优化后只算5次。数越大节省时间越多                for(k = 1 ; k < num[i]; num[i]-=k , k*=2)                    for(j=n; j>=k*value[i]; j--)                        dp[j] = max(dp[j],dp[j-k*value[i]]+k*weight[i]);                 //处理二进制化后的余数部分                                     for(j = n ; j >= num[i]*value[i] ; j--)                        dp[j] = max(dp[j],dp[j-num[i]*value[i]]+num[i]*weight[i]);              }                                                       }        printf("%d\n", dp[n]);    }    return 0;}
0 0
原创粉丝点击