POJ 1276 Cash Machine

解题思路:dp(多重背包问题)

将多重背包转化为01背包,假设每个物品的数量上限为n,每件的体积为0,价值为w

那么可以把该物品分为1,2,4,...,2^(k-1)和n-(2^k+1),那么新的物品就是(体积,价值):(0,w),(0,2w),...,(0,2^(k-1)w)和(0,(n-2^k+1)w)

(这样可以构造出任何<=n的情况,假设n为7,则分成系数为1,2和4,那么1-7的所有情况均可由1,2,4这3个基数组合得到)

NULL
#include <iostream>
using namespace std;
#define MAXN 100001
int main()
{
int c,m,i,j,k,t,p;
int d[11],n[11],dp[MAXN];
while(scanf("%d %d", &c, &m)!=EOF)
{
for(i=0;i<m;i++)scanf("%d %d", &n[i], &d[i]);
memset(dp,
0, sizeof(dp));
for(i=0;i<m;i++)
if(n[i]*d[i]==c){dp[c]=c;break;}
else if(n[i]*d[i]>c)
{
for (j=d[i];j<=c;j++)
if(dp[j-d[i]]+d[i]>dp[j])dp[j]=dp[j-d[i]]+d[i];
}
else
{
for(t=n[i],j=1;j<=(n[i]>>1);t-=j,j*=2)
for(k=c,p=j*d[i];k>=p;k--)
if(dp[k-p]+p>dp[k])dp[k]=dp[k-p]+p;
for(k=c,p=t*d[i];k>=p;k--)
if(dp[k-p]+p>dp[k])dp[k]=dp[k-p]+p;
}
printf(
"%d\n",dp[c]);
}
return 0;
}

 

posted on 2010-12-22 14:48  ltang  阅读(175)  评论(0编辑  收藏  举报

导航