题目链接:
题目大意:
给n块砖的长度(n<=100),问从中任选m块砖能否建成2个相同高度的塔。
能的话求最高高度,不能输出 Impossible 。
题目思路:
【动态规划】
想了好久f[i][j]表示前 i 块砖较矮的塔高度为 j 时 塔的差距,结果发现推不出状态。
后来改了,f[i][j]表示前 i 块砖差距为 j 时 较矮的塔的高度,那么有4种情况。
①不取 ②取完放到高的 ③取完放到矮的但是矮的依旧矮 ④取完放到矮的矮的变成高的。
最后看f[n][0]。
1 // 2 //by coolxxx 3 ////<bits/stdc++.h> 4 #include<iostream> 5 #include<algorithm> 6 #include<string> 7 #include<iomanip> 8 #include<memory.h> 9 #include<time.h> 10 #include<stdio.h> 11 #include<stdlib.h> 12 #include<string.h> 13 //#include<stdbool.h> 14 #include<math.h> 15 #define min(a,b) ((a)<(b)?(a):(b)) 16 #define max(a,b) ((a)>(b)?(a):(b)) 17 #define abs(a) ((a)>0?(a):(-(a))) 18 #define lowbit(a) (a&(-a)) 19 #define sqr(a) ((a)*(a)) 20 #define swap(a,b) ((a)^=(b),(b)^=(a),(a)^=(b)) 21 #define mem(a,b) memset(a,b,sizeof(a)) 22 #define eps (1e-8) 23 #define J 10 24 #define MAX 0x7f7f7f7f 25 #define PI 3.14159265358979323 26 #define N 104 27 #define M 2004 28 using namespace std; 29 typedef long long LL; 30 int cas,cass; 31 int n,m,lll,ans; 32 int a[N]; 33 int f[N][M]; 34 void print() 35 { 36 int i,j; 37 for(i=1;i<=n;i++) 38 { 39 for(j=0;j<=m;j++) 40 printf("%d ",f[i][j]); 41 puts(""); 42 } 43 } 44 int main() 45 { 46 #ifndef ONLINE_JUDGE 47 // freopen("1.txt","r",stdin); 48 // freopen("2.txt","w",stdout); 49 #endif 50 int i,j,k,l; 51 // for(scanf("%d",&cas);cas;cas--) 52 // for(scanf("%d",&cas),cass=1;cass<=cas;cass++) 53 // while(~scanf("%s",s)) 54 while(~scanf("%d",&n)) 55 { 56 mem(f,-1); 57 m=0; 58 for(i=1;i<=n;i++) 59 { 60 scanf("%d",&a[i]); 61 m+=a[i]; 62 } 63 if(n<2){puts("Impossible");continue;} 64 f[0][0]=0; 65 for(i=1;i<=n;i++) 66 { 67 for(j=0;j<=m;j++) 68 { 69 f[i][j]=max(f[i][j],f[i-1][j]); 70 f[i][j+a[i]]=max(f[i][j+a[i]],f[i-1][j]); 71 if(j>=a[i] && f[i-1][j]!=-1) 72 f[i][j-a[i]]=max(f[i][j-a[i]],f[i-1][j]+a[i]); 73 else if(j<a[i] && f[i-1][j]!=-1) 74 f[i][a[i]-j]=max(f[i][a[i]-j],f[i-1][j]+j); 75 } 76 } 77 if(f[n][0]>0)printf("%d ",f[n][0]); 78 else puts("Impossible"); 79 //print(); 80 } 81 return 0; 82 } 83 /* 84 // 85 86 // 87 */