HJ93 数组分组
题目:https://www.nowcoder.com/practice/9af744a3517440508dbeb297020aca86?tpId=37&tqId=21316&rp=1&ru=/exam/oj/ta&qru=/exam/oj/ta&sourceUrl=%2Fexam%2Foj%2Fta%3FtpId%3D37&difficulty=undefined&judgeStatus=undefined&tags=&title=
最大的收获是学会了在数组中使用负数下标:
bool u[maxn][55];
#define dp (u+(maxn>>1))
本质就是数组指针+偏移量。
dp[j][i]表示前i个数,是否能够合成和为j的情况。
预处理一下就行.
1 #include<bits/stdc++.h> 2 using namespace std; 3 int n,a[55],sum=0; 4 const int maxn=55000; 5 bool u[maxn][55]; 6 #define dp (u+(maxn>>1)) 7 int fenzu(int x){ 8 if(x%5==0) return 1; 9 if(x%3==0) return 2; 10 return 0; 11 } 12 void init(){ 13 cin>>n; 14 for(int i=1;i<=n;i++){ 15 scanf("%d",&a[i]); 16 sum+=a[i]; 17 } 18 return; 19 } 20 void DP(){ 21 if(!fenzu(a[1])){ 22 dp[a[1]][1]=1; 23 dp[0][1]=1; 24 } 25 else if(fenzu(a[1])==1) 26 dp[a[1]][1]=1; 27 else dp[0][1]=1; 28 for(int i=2;i<=n;i++){ 29 for(int j=-25000;j<=25000;j++){ 30 if(fenzu(a[i])==0){ 31 dp[j][i]=max(dp[j][i],dp[j-a[i]][i-1]); 32 dp[j][i]=max(dp[j][i],dp[j][i-1]); 33 } 34 if(fenzu(a[i])==1){ 35 dp[j][i]=max(dp[j][i],dp[j-a[i]][i-1]); 36 } 37 if(fenzu(a[i])==2) dp[j][i]=max(dp[j][i],dp[j][i-1]); 38 } 39 } 40 return; 41 } 42 void Output(int x){ 43 if(x) { 44 puts("true"); 45 exit(0); 46 } 47 else { 48 puts("false"); 49 exit(0); 50 } 51 return; 52 } 53 int main(){ 54 init(); 55 if(sum%2) Output(0); 56 DP(); 57 if(dp[sum/2][n]) Output(1); 58 else Output(0); 59 return 0; 60 }