这个题是一个背包的问题,好久没有写过背包了,,,
不过也可以YY,,,
先说下YY的做法:如果给出的n个数中只有200的话,那么这 n 个数的和能被400整除就说明可以平分,否则不能
如果这 n 个数中有100出现,那么,如果这 n 个数的和能被200 整除就说明能够平分,否则不能
代码如下:
Result : Accepted Time : 62 ms Memory : 4 KB
/* * Author: Gatevin * Created Time: 2014/5/24 15:01:25 * File Name: test_for.cpp */ #include<iostream> #include<sstream> #include<fstream> #include<vector> #include<list> #include<deque> #include<queue> #include<stack> #include<map> #include<set> #include<bitset> #include<algorithm> #include<cstdio> #include<cstdlib> #include<cstring> #include<cctype> #include<cmath> #include<ctime> using namespace std; const double eps(1e-8); typedef long long lint; #define clr(x) memset( x , 0 , sizeof(x) ) #define sz(v) ((int)(v).size()) #define rep(i, n) for (int i = 0; i < (n); i++) #define rise(i, a, b) for (int i = (a); i <= (b); i++) #define fall(i, a, b) for (int i = (a); i >= (b); i--) #define clrs( x , y ) memset( x , y , sizeof(x) ) int a[101]; int main() { int n; cin>>n; int ans = 0; bool flag = false; int cnt2 = 0; for(int i = 1; i <= n; i++) { cin>>a[i]; if(a[i] == 100) { flag = true; } else { cnt2++; } ans += a[i]; } if(flag) { if(ans%400 == 0) { cout<<"YES"<<endl; } else { if(ans%200 == 0) { cout<<"YES"<<endl; } else { cout<<"NO"<<endl; } } } else { if(cnt2 & 1) { cout<<"NO"<<endl; } else { cout<<"YES"<<endl; } } return 0; }
标答是用的背包
用 f [ i ][ j ] 表示前 i 个物品能否取得和为 j 的情况, 则 f [ i ][ j ] = f [i - 1][j] || f [ i - 1][ j - v[ i ] ] , v [ i ] 表示第 i 个物品的价值
这里物品的价值都是100 或 200 可以用 1 和 2 来表示
最终如果 f [ n ][ sum / 2 ] 为true则可行(sum 为偶数时, 显然sum为奇数是不行的)
代码如下 :
Result : Accepted Time : 31 ms Memory : 24 KB
/* * Author: Gatevin * Created Time: 2014/5/25 18:04:04 * File Name: test_for.cpp */ #include<iostream> #include<sstream> #include<fstream> #include<vector> #include<list> #include<deque> #include<queue> #include<stack> #include<map> #include<set> #include<bitset> #include<algorithm> #include<cstdio> #include<cstdlib> #include<cstring> #include<cctype> #include<cmath> #include<ctime> using namespace std; const double eps(1e-8); typedef long long lint; #define clr(x) memset( x , 0 , sizeof(x) ) #define sz(v) ((int)(v).size()) #define rep(i, n) for (int i = 0; i < (n); i++) #define rise(i, a, b) for (int i = (a); i <= (b); i++) #define fall(i, a, b) for (int i = (a); i >= (b); i--) #define clrs( x , y ) memset( x , y , sizeof(x) ) int V[101]; bool f[101][201]; int main() { int n; int tmp; int sum = 0; cin>>n; for(int i = 1; i <= n; i++) { cin>>tmp; V[i] = tmp/100; sum += V[i]; } memset(f, 0, sizeof(f)); f[0][0] = true; for(int i = 1; i <= n; i++) { f[i][0] = true; } for(int i = 1; i <= n; i++) { for(int j = 0; j <= sum; j++) { if(j >= V[i]) { f[i][j] = f[i - 1][j - V[i]] || f[i - 1][j]; } else { f[i][j] = f[i - 1][j]; } } } if(sum & 1) { cout<<"NO"<<endl; } else { if(f[n][sum/2]) { cout<<"YES"<<endl; } else { cout<<"NO"<<endl; } } return 0; }