HDU Coins【多重バックパック問題】
1675 ワード
考え方:
時計の価格はm元で、硬貨の中でいくつかの硬貨を選んでいくつかの異なる総価値pを構成します(そしてその総価値pを(1->m)の間に)
ACコード:
時計の価格はm元で、硬貨の中でいくつかの硬貨を選んでいくつかの異なる総価値pを構成します(そしてその総価値pを(1->m)の間に)
ACコード:
#include<stdio.h>
#include<string.h>
int dp[100005],c[105],v[105];
int m;
void CompletePack(int c,int w)
{
int i;
for(i=c;i<=m;i++)
if(dp[i]<dp[i-c]+w)
{
dp[i]=dp[i-c]+w;
}
}
void ZeroOnePack(int c,int w)
{
int i;
for(i=m;i>=c;i--)
if(dp[i]<dp[i-c]+w)
{
dp[i]=dp[i-c]+w;
}
}
void MultiPack(int c,int w,int amount)
{
int k;
if(c*amount>m)
{
CompletePack(c,w);
return ;
}
k=1;
while(k<amount)
{
ZeroOnePack(k*c,k*w);
amount-=k;
k*=2;
}
ZeroOnePack(amount*c,amount*w);
}
int main()
{
int n;
int i,j;
int count;
int flag[100005];
while(scanf("%d%d",&n,&m)!=-1&&(n+m))
{
for(i=1;i<=n;i++)
scanf("%d",&v[i]);
for(i=1;i<=n;i++)
scanf("%d",&c[i]);
memset(dp,0,sizeof(dp));
for(i=1;i<=n;i++)
MultiPack(v[i],v[i],c[i]);
j=1;
for(i=m;i>=1;i--)
if(dp[i])flag[j++]=dp[i];/* 1->m 0 */
count=j-1;/* , */
for(i=2;i<=j-1;i++)
if(flag[i]==flag[i-1])count--;/* flag , , 1*/
printf("%d
",count);
}
return 0;
}