题目描述
魔法世界发行了很多不同面值的纸币,试求出用这些纸币进行任意的组合不能表示的最小面值是多少。
输入
输入包含多个测试用例,每组测试用例的第一行输入一个整数N(N≤100)表示流通的纸币面额数量,第二行是N个纸币的具体表示面额,取值范围为1~100。
输出
对于每组测试用例,输出一个整数,表示已经发行的所有纸币都不能表示的最小面值(已经发行的每个纸币面值最多只能使用一次,但面值可能有重复)。
样例输入
5
1 2 3 9 100
5
1 2 4 9 100
5
1 2 4 7 100
样例输出
7 8 15
#include<iostream> using namespace std; int main() { int n; while(cin>>n) { int a[105]={0}; int sum = 0; for(int i=0;i<n;i++) { cin>>a[i]; sum += a[i]; } int dp[10005]={0}; for(int i=0;i<n;i++) { for(int j=sum;j>=a[i];j--) { dp[j] = max(dp[j],dp[j-a[i]]+a[i]); } } int flag = 0; for(int i=1;i<=sum;i++) { if(dp[i]!=i) { flag = 1; cout<<i<<endl; break; } } if(!flag) //******** cout<<sum+1<<endl; } return 0; }
一道变向0/1背包问题
给你几个数 问你不能组合成的最小的数,组合成一个数,面对其中一个元素 无非就是选与不选 ,而01背包中dp[i]表示背包为i大小的时候 最大能装的价值
我们这道题dp[i]表示的是这个背包能组合成的最大的数,这个数不会超过i的大小,所以如果dp[i]==i则说明能够组合成这个数字。那么,如果dp[i]!=i的话
就是无法组成这个数。
将i从1到sum遍历一次 就能找到最小的 无法组合的数
注意:打*的代码容易忽略 我就wa了一发 如果从1到sum都能组成 那么最小不能组成的数就是sum+1了