原题链接:

http://hihocoder.com/problemset/problem/1353


题意:

给你一个数列和一个m,从数列里选任意的数,使他们的和大于等于m又是最小,输出这个和。如果不存在输出-1。


分析:

这题一上去,感觉是贪心,然后排个序从大加,加到大于等于m就跳出,交一发直接WA了。然后感觉是二分,枚举m到sum,每次找到小于m最近的数,然后减去这个数。WA了6发,不断地测试数据,一直能找到数据过不了,最终放弃了这种算法,写了一个dfs,20!的复杂度,抱着玩的心态交了一发,果断超时。
但是总觉得这题肯定很简单,最终实在不想想了,结果就看了一下大神的代码,崩溃了,什么算法都有。。
对比一下别人的代码,同样是dfs,人家就是O(2^n),其实dp也应该更加容易想到,复杂度还比dfs低。枚举m到sum,跑01背包就行了。


代码:

贪心WA:

 1 #include <iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<vector>
 5 #include<set>
 6 #include<map>
 7 #include<algorithm>
 8 #include<string>
 9 #include<queue>
10 #include<cmath>
11 #include<stack>
12 #include<cctype>
13 #include<list>
14 
15 
16 #define ll long long
17 #define ull unsigned long long
18 #define VNAME(name) (#name)
19 #define debug(a) cout<<VNAME(a)<<" = "<<(a)<<endl;
20 #define SI(a) cin>>(a)
21 #define SII(a,b) cin>>(a)>>(b)
22 #define PI(a) cout<<(a)
23 #define PIE(a) cout<<(a)<<endl
24 #define MST(a) memset((a),0,sizeof((a)))
25 
26 using namespace std;
27 
28 const int maxn = 110;
29 const int inf = 1 << 30;
30 int num[maxn];
31 
32 int main() {
33     iostream::sync_with_stdio(false);
34 
35 #ifndef ONLINE_JUDGE
36     freopen("in.txt", "r", stdin);
37     //freopen("out.txt","w",stdout);
38 #endif
39     int n, m;
40     while(SII(n, m)) {
41         int sum = 0;
42         for(int i = 0; i < n; i++) {
43             SI(num[i]);
44 
45         }
46         sort(num, num + n);
47         for(int i = 0; i < n; i++) {
48             sum += num[i];
49             if(sum >= m) {
50                 break;
51             }
52         }
53         if(sum<m){
54             puts("-1");
55         }
56         else{
57             PIE(sum);
58         }
59     }
60     return 0;
61 }
View Code

二分WA:

 1 #include <iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<vector>
 5 #include<set>
 6 #include<map>
 7 #include<algorithm>
 8 #include<string>
 9 #include<queue>
10 #include<cmath>
11 #include<stack>
12 #include<cctype>
13 #include<list>
14 
15 
16 #define ll long long
17 #define ull unsigned long long
18 #define VNAME(name) (#name)
19 #define debug(a) cout<<VNAME(a)<<" = "<<(a)<<endl;
20 #define SI(a) cin>>(a)
21 #define SII(a,b) cin>>(a)>>(b)
22 #define PI(a) cout<<(a)
23 #define PIE(a) cout<<(a)<<endl
24 #define MST(a) memset((a),0,sizeof((a)))
25 
26 using namespace std;
27 
28 const int maxn = 21;
29 const int inf = 1 << 30;
30 int num[maxn];
31 int n,m;
32 
33 int main() {
34     iostream::sync_with_stdio(false);
35 
36 #ifndef ONLINE_JUDGE
37     //freopen("in.txt", "r", stdin);
38     //freopen("out.txt","w",stdout);
39 #endif
40 
41     while(SII(n, m)) {
42         int sum = 0;
43         for(int i = 0; i < n; i++) {
44             SI(num[i]);
45             sum+=num[i];
46         }
47         if(sum<m){
48             puts("-1");
49             continue;
50         }
51         int tmp[maxn];
52         for(int i=m;i<=sum;i++){
53             int x=i;
54             int flag=0;
55             for(int j=0;j<n;j++){
56                 tmp[j]=num[j];
57             }
58             while(1){
59                 sort(tmp,tmp+n);
60                 int d=lower_bound(tmp,tmp+n,x)-tmp;
61                 if(tmp[d]==x){
62                     flag=1;
63                     PIE(i);
64                     break;
65                 }
66                 else{
67                     if(d==0){
68                         break;
69                     }
70                     else{
71                         x-=tmp[d-1];
72                         tmp[d-1]=inf;
73                     }
74                 }
75                 //PIE(x);
76             }
77             if(flag)break;
78 
79         }
80 
81     }
82     return 0;
83 }
View Code

相关文章: