9.28T3 思维水题

1、志愿填报4719

 gaokao

【问题描述】

众所周知,今天是高考的第二天,正所谓“月儿弯弯照九州,几家欢喜几家愁”。而高考志愿填报更是抉择的时候,其中每年的高考的志愿填报都是使用的 1、2、4、8 来表示数字,如要填涂 7 则选择 1、2、4 三个数字, Pray2018 作为 1‰的数学爱好者,他决定研究这一问题, 即, 给出 n 个互不相同的正整数, 记为 s[i] , 每个正整数只能使用一次,求这 n 个数 不能组合得到的最小值。

【输入说明】

第一行是一个正整数 n,表示正整数的个数。
接下来的 n 行每行一个正整数。

【输出说明】

一个正整数,表示这 n 个数 不能组合得到的最小值。

【样例输入】

4 1 2 4 8

【样例输出】

16

【数据规模 与约定】
对于 30%的数据,n<=500,s[i]<=1000;
对于 70%的数据,n<=1000,s[i]<=10000;
对于 100%的数据,n<=100000,s[i]<=100000。

 

 

 

1.此题解法可用01背包,只要你不爆炸(滑稽)

2、我们假设前i个数中1->sum的值已经可以全部达到,那么如果S[i+1]>sum+1,则sum+1无法取得。否则可以表示出1->sum+S[i+1]的值。所以可以对序列S排序,然后水过。

3、歪门邪道:我们可以想到,这道题的数据并不好生成,尤其在数据较大的时候,无法达到的值很容易就变成了S[i]累加起来加1,而这种方法可以水过60分。

这题实际上就与去年的小凯的疑惑很像,但是完全不同,这题纯粹靠乱搞(哈哈哈哈哈哈哈哈

不过正经的来说,我们其实首先应该有最优化排序的意识,01背包的实质在于更新,但这道题的特点是找出最小,所以我们并不关心那些很大的值,我们只关心能不能凑出小的值,尤其是这个1->sum思想

code:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 using namespace std;
 5 int a[1000005];
 6 int main(){
 7     int n;
 8     cin>>n;
 9     for(int i=1;i<=n;i++)cin>>a[i];
10     sort(a+1,a+n+1);
11     int sum=0;
12     for(int i=1;i<=n;i++){
13         if(sum+1<a[i])break;
14         sum+=a[i];
15     }
16     cout<<sum+1;
17     return 0;
18 }

over

posted @ 2018-09-28 21:50  saionjisekai  阅读(62)  评论(0编辑  收藏  举报