题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1085
给定1,2,5枚硬币个数,问最少不能凑到多少钱。
先想到的是背包的解法。
多重背包:
#include <bits/stdc++.h>
using namespace std;
int dp[8005];
int value[4] = {1, 2, 5};
int num[4];
int cnt[8005];
int main() {
while (scanf("%d%d%d", num, num + 1, num + 2), num[0] + num[1] + num[2]) {
memset(dp, 0, sizeof(dp));
dp[0] = 1;
int sum = num[0] + num[1] * 2 + num[2] * 5;
for (int i = 0; i < 3; i ++) {
memset(cnt, 0, sizeof(cnt));
for (int j = value[i]; j <= sum; j ++) {
if(dp[j-value[i]] == 1 && dp[j] == 0 && cnt[j-value[i]] < num[i]) {
dp[j] = 1;
cnt[j] = cnt[j-value[i]] + 1;
}
}
}
int i = 0;
for (i = 0; i <= sum + 1; i ++) {
if(dp[i] == 0) {
printf("%d\n", i);
break;
}
}
}
return 0;
}
然后发现数学方法更快,只要凑出1,2,3,4,5,那么最大不能凑到的值就是sum+1.(代码直接复制队友的了。。。。)
#include <iostream>
#include <cstdio>
#include <cstdlib>
using namespace std;
int main(){
int n1,n2,n3;
while( scanf("%d%d%d",&n1,&n2,&n3)!=EOF ){
if( n1 == 0 && n2 == 0 && n3 == 0 ){
break;
}
for( int i = 1; i <= 5; i++ ){
if( i == 1 ){
if( n1 == 0 ){
printf("%d\n",i);
break;
}
}
else if( i < 5 && i >= 2 ){
if( n2*2 + n1 < i ){
printf("%d\n",i);
break;
}
}
else{
printf("%d\n",5*n3+2*n2+1*n1+1);
break;
}
}
}
}