【动态规划】Vijos P1037 搭建双塔

来源:互联网 发布:上海市人口普查数据 编辑:程序博客网 时间:2024/05/16 14:58
题目链接:

  https://vijos.org/p/1037

题目大意:

  给n块砖的长度(n<=100),问从中任选m块砖能否建成2个相同高度的塔。

  能的话求最高高度,不能输出 Impossible 。

题目思路:

  【动态规划】

  想了好久f[i][j]表示前 i 块砖较矮的塔高度为 j 时 塔的差距,结果发现推不出状态。

  后来改了,f[i][j]表示前 i 块砖差距为 j 时 较矮的塔的高度,那么有4种情况。

  ①不取  ②取完放到高的  ③取完放到矮的但是矮的依旧矮  ④取完放到矮的矮的变成高的。

   最后看f[n][0]。

 

////by coolxxx////<bits/stdc++.h>#include<iostream>#include<algorithm>#include<string>#include<iomanip>#include<memory.h>#include<time.h>#include<stdio.h>#include<stdlib.h>#include<string.h>//#include<stdbool.h>#include<math.h>#define min(a,b) ((a)<(b)?(a):(b))#define max(a,b) ((a)>(b)?(a):(b))#define abs(a) ((a)>0?(a):(-(a)))#define lowbit(a) (a&(-a))#define sqr(a) ((a)*(a))#define swap(a,b) ((a)^=(b),(b)^=(a),(a)^=(b))#define mem(a,b) memset(a,b,sizeof(a))#define eps (1e-8)#define J 10#define MAX 0x7f7f7f7f#define PI 3.14159265358979323#define N 104#define M 2004using namespace std;typedef long long LL;int cas,cass;int n,m,lll,ans;int a[N];int f[N][M];void print(){int i,j;for(i=1;i<=n;i++){for(j=0;j<=m;j++)printf("%d ",f[i][j]);puts("");}}int main(){#ifndef ONLINE_JUDGE//freopen("1.txt","r",stdin);//freopen("2.txt","w",stdout);#endifint i,j,k,l;//for(scanf("%d",&cas);cas;cas--)//for(scanf("%d",&cas),cass=1;cass<=cas;cass++)//while(~scanf("%s",s))while(~scanf("%d",&n)){mem(f,-1);m=0;for(i=1;i<=n;i++){scanf("%d",&a[i]);m+=a[i];}if(n<2){puts("Impossible");continue;}f[0][0]=0;for(i=1;i<=n;i++){for(j=0;j<=m;j++){f[i][j]=max(f[i][j],f[i-1][j]);f[i][j+a[i]]=max(f[i][j+a[i]],f[i-1][j]);if(j>=a[i] && f[i-1][j]!=-1)f[i][j-a[i]]=max(f[i][j-a[i]],f[i-1][j]+a[i]);else if(j<a[i] && f[i-1][j]!=-1)f[i][a[i]-j]=max(f[i][a[i]-j],f[i-1][j]+j);}}if(f[n][0]>0)printf("%d\n",f[n][0]);else puts("Impossible");//print();}return 0;}/*////*/


0 0