【动态规划】货币面值

题目描述

魔法世界发行了很多不同面值的纸币,试求出用这些纸币进行任意的组合不能表示的最小面值是多少。

输入

输入包含多个测试用例,每组测试用例的第一行输入一个整数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了

原文地址:https://www.cnblogs.com/hao-tian/p/9427031.html