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;
}