zcmu-2137
2137: 和為T
Time Limit:?1 Sec??Memory Limit:?128 MBSubmit:?66??Solved:?14
[Submit][Status][Web Board]
Description
從一個大小為n的整數集中選取一些元素,使得它們的和等于給定的值T。每個元素限選一次,不能一個都不選。
Input
第一行一個正整數n,表示整數集內元素的個數。
第二行n個整數,用空格隔開。
第三行一個整數T,表示要達到的和。
Output
輸出有若干行,每行輸出一組解,即所選取的數字,按照輸入中的順序排列。
若有多組解,優先輸出不包含第n個整數的;若都包含或都不包含,優先輸出不包含第n-1個整數的,依次類推。
最后一行輸出總方案數。
Sample Input
5-7 -3 -2 5 90Sample Output
-3 -2 5 -7 -2 9 2HINT
1<=n<=22,T<=maxlongint
解析:根據題目要求,從前往后枚舉,可以發現一個規律。| 9 | 5 | -2 | -3 | -7 |
| 0 | 0 | 0 | 0 | 1 |
| 0 | 0 | 0 | 1 | 0 |
| 0 | 0 | 0 | 1 | 1 |
| 0 | 0 | 1 | 0 | 0 |
| 0 | 0 | 1 | 1 | 0 |
| 0 | 0 | 1 | 1 | 1 |
| 0 | 1 | 0 | 0 | 0 |
這就是二進制枚舉。但是這里卻超時了。所以、換另外的一個寫法,dfs。
dfs:
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<cctype> #include<cstdlib> #include<algorithm> #include<vector> #include<set> #include<map> #include<stack> #include<list> using namespace std; int v[22]; int q[22]; int n,ans,cnt=0; void result(int t) { if(t<0) { int sum=0,sumofv=0; for(int i=0;i<n;i++) { if(v[i]) sum+=q[i]; sumofv+=v[i]; } if(sum==ans&&sumofv) { for(int i=0;i<n;i++) if(v[i]) cout<<q[i]<<" "; cout<<endl; cnt++; } return; } for(int i=0;i<=1;i++) { v[t]=i; result(t-1); } } int main() { cin>>n; for(int i=0;i<n;i++) cin>>q[i]; cin>>ans; result(n-1); cout<<cnt<<endl; return 0; }超時的二進制枚舉法:
#include<bits/stdc++.h> using namespace std;typedef long ll;int main() {int n;ll t;ll a[200];while(~scanf("%d",&n)){int ans=0;for(int i=0; i<n; i++)scanf("%lld",&a[i]);scanf("%lld",&t);for(int i=1; i<(1<<n); i++){ll sum=0;for(int j=0; j<n; j++){if(i&(1<<j))sum+=a[j];}if(sum==t){for(int j=0; j<n; j++){if(i&(1<<j))printf("%lld ",a[j]);}puts("");ans++;}}printf("%d\n",ans);}return 0; }總結
- 上一篇: JMS学习二(简单的ActiveMQ实例
- 下一篇: 互联网晚报 | 2月20日 星期日 |