首页 > 代码库 > hdu 3591 多重加完全DP
hdu 3591 多重加完全DP
题目:
The trouble of Xiaoqian
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1997 Accepted Submission(s):
711
Problem Description
In the country of ALPC , Xiaoqian is a very famous
mathematician. She is immersed in calculate, and she want to use the minimum
number of coins in every shopping. (The numbers of the shopping include the
coins she gave the store and the store backed to her.)
And now , Xiaoqian wants to buy T (1 ≤ T ≤ 10,000) cents of supplies. The currency system has N (1 ≤ N ≤ 100) different coins, with values V1, V2, ..., VN (1 ≤ Vi ≤ 120). Xiaoqian is carrying C1 coins of value V1, C2 coins of value V2, ...., and CN coins of value VN (0 ≤ Ci ≤ 10,000). The shopkeeper has an unlimited supply of all the coins, and always makes change in the most efficient manner .But Xiaoqian is a low-pitched girl , she wouldn’t like giving out more than 20000 once.
And now , Xiaoqian wants to buy T (1 ≤ T ≤ 10,000) cents of supplies. The currency system has N (1 ≤ N ≤ 100) different coins, with values V1, V2, ..., VN (1 ≤ Vi ≤ 120). Xiaoqian is carrying C1 coins of value V1, C2 coins of value V2, ...., and CN coins of value VN (0 ≤ Ci ≤ 10,000). The shopkeeper has an unlimited supply of all the coins, and always makes change in the most efficient manner .But Xiaoqian is a low-pitched girl , she wouldn’t like giving out more than 20000 once.
Input
There are several test cases in the input.
Line 1: Two space-separated integers: N and T.
Line 2: N space-separated integers, respectively V1, V2, ..., VN coins (V1, ...VN)
Line 3: N space-separated integers, respectively C1, C2, ..., CN
The end of the input is a double 0.
Line 1: Two space-separated integers: N and T.
Line 2: N space-separated integers, respectively V1, V2, ..., VN coins (V1, ...VN)
Line 3: N space-separated integers, respectively C1, C2, ..., CN
The end of the input is a double 0.
Output
Output one line for each test case like this ”Case X:
Y” : X presents the Xth test case and Y presents the minimum number of coins .
If it is impossible to pay and receive exact change, output -1.
Sample Input
3 70
5 25 50
5 2 1
0 0
Sample Output
Case 1: 3
题意 给出硬币的种类面额和数量,要购买的物品总价格,求交易时最小的经手货币量;
每种硬币数量可多达一万,所以使用二进制优化数量,又最多支付2w,所以默认背包为2w大小;
店家货币无限,所以为完全背包,小倩是一个多重背包;
代码:
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
#define inf 999999999
int main()
{
int T,N,c[105],v[105],dp[20001],i,j,k,a[105],b[105],
dp2[20001],x=0;
while (cin>>N>>T&&N&&T){x++;
int min_num=inf;
memset(dp,63,sizeof(dp));dp[0]=0;
memset(dp2,63,sizeof(dp2));dp2[0]=0;
for (i=1;i<=N;i++) scanf("%d",&v[i]);
for (i=1;i<=N;i++) scanf("%d",&c[i]);
for (i=1;i<=N;i++){
int count=1;
for (k=1;c[i];k*=2){ //二进制优化硬币数量,顺便记录下每种情况所需硬币多少便于优化后01背包的完成
if (c[i]<k) k=c[i];
a[count]=k*v[i];
b[count++]=k;
c[i]-=k;
}
for (k=1;k<count;k++) //优化之后进行一次01背包
for (j=20000;j>=a[k];j--)
dp[j]=min(dp[j],dp[j-a[k]]+b[k]);
}
for (i=1;i<=N;i++) //对商店进行的完全背包
for (j=v[i];j<=20000;j++)
dp2[j]=min(dp2[j],dp2[j-v[i]]+1);
for (i=T;i<=20000;i++) //计算 T---2w间最小经手硬币数量
min_num=min(min_num,dp[i]+dp2[i-T]);
printf("Case %d: ",x);
if (min_num==inf) cout<<"-1"<<endl;
else cout<<min_num<<endl;
}
return 0;
}
小坑---inf和memset赋值#include<cstring>
#include<cstdio>
using namespace std;
#define inf 999999999
int main()
{
int T,N,c[105],v[105],dp[20001],i,j,k,a[105],b[105],
dp2[20001],x=0;
while (cin>>N>>T&&N&&T){x++;
int min_num=inf;
memset(dp,63,sizeof(dp));dp[0]=0;
memset(dp2,63,sizeof(dp2));dp2[0]=0;
for (i=1;i<=N;i++) scanf("%d",&v[i]);
for (i=1;i<=N;i++) scanf("%d",&c[i]);
for (i=1;i<=N;i++){
int count=1;
for (k=1;c[i];k*=2){ //二进制优化硬币数量,顺便记录下每种情况所需硬币多少便于优化后01背包的完成
if (c[i]<k) k=c[i];
a[count]=k*v[i];
b[count++]=k;
c[i]-=k;
}
for (k=1;k<count;k++) //优化之后进行一次01背包
for (j=20000;j>=a[k];j--)
dp[j]=min(dp[j],dp[j-a[k]]+b[k]);
}
for (i=1;i<=N;i++) //对商店进行的完全背包
for (j=v[i];j<=20000;j++)
dp2[j]=min(dp2[j],dp2[j-v[i]]+1);
for (i=T;i<=20000;i++) //计算 T---2w间最小经手硬币数量
min_num=min(min_num,dp[i]+dp2[i-T]);
printf("Case %d: ",x);
if (min_num==inf) cout<<"-1"<<endl;
else cout<<min_num<<endl;
}
return 0;
}
最好让两者在inf小于memset情况下两者总和不要超出int,否则爆出负数就会wa
hdu 3591 多重加完全DP
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。