Hrbust-2090 背包(最小不可构造数)

这里写图片描述

和背包没什么关系,记得之前有到题是关于奖券的,根据不同面值的奖券能组合出连续的最大值就是奖券能消费的值。都是求最小不可构造数首先肯定要有1,然后我们遍历下一个2是否能组合出来…..一个递推的过程。判断一个值是否可以构造出来,取一个最小的值判断其是否小于等于被构造的值,首先确定加入上一个最小值后的那个总和是可以被构造出来的,那么加入新的最小值扩充了这个sum求和,如,1,1,1,1,1的sum为5,那么如果我加入一个新值3,小于5,于是大于5的值,都可以依托新加入的值3,而构造出来,因为1~5可以构造,那么随意取一个可构造的值加上3,即5往后的3个值全部可以构造。

sum表示将要表示的下一个数。如,先判断sum=1时,是否能构造,如果最小的数都大于1,那么就无法构造,如果能构造,那说明有1,加到sum上,sum=2,再用下一个a[i]判断是否能构造出2这个数。

如果下一个a[i]>sum,也就是说除了1外无法构造出2本身,就break掉。 接下来的3,4,5同理,如果有了1,2,再判断3,有了1,2,3再判断6,如果a[i]<6那么就可以被之前存在的任一一个数构造出来。如果a[i]比sum还大,那么从上一个数到sum这段区间就有数无法表示

#include<stdio.h>
int n,i,a[10000005];
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        for(i=0;i<n;i++) scanf("%d",&a[i]);
        long long sum=1;
        for(i=0;i<n;i++)
            if(a[i]<=sum)///判断在有序的序列中,是否能利用当前a[i]表示sum
                sum+=a[i];
            else
                break;
        printf("%lld\n",sum);
    }
    return 0;
}
posted @ 2018-06-22 00:24  KuroNekonano  阅读(141)  评论(0编辑  收藏  举报