描述
2001年9月11日,一場突發的災難將紐約世界貿易中心大廈夷爲平地,Mr. F曾親眼目睹了這次災難。爲了紀念“9?11”事件,Mr. F決定自己用水晶來搭建一座雙塔。
Mr. F有N塊水晶,每塊水晶有一個高度,他想用這N塊水晶搭建兩座有同樣高度的塔,使他們成爲一座雙塔,Mr. F可以從這N塊水晶中任取M(1≤M≤N)塊來搭建。但是他不知道能否使兩座塔有同樣的高度,也不知道如果能搭建成一座雙塔,這座雙塔的最大高度是多少。所以他來請你幫忙。
給定水晶的數量N(1≤N≤100)和每塊水晶的高度Hi(N塊水晶高度的總和不超過2000),你的任務是判斷Mr. F能否用這些水晶搭建成一座雙塔(兩座塔有同樣的高度),如果能,則輸出所能搭建的雙塔的最大高度,否則輸出“Impossible”。
格式
輸入格式
輸入的第一行爲一個數N,表示水晶的數量。第二行爲N個數,第i個數表示第i個水晶的高度。
輸出格式
輸出僅包含一行,如果能搭成一座雙塔,則輸出雙塔的最大高度,否則輸出一個字符串“Impossible”。
樣例1
樣例輸入1
5
1 3 4 5 2
樣例輸出1
7
思路:感覺像01揹包,而且這題的思路很好,dp[i][j],i是第一個塔的高度,j是第二個塔的高度,這個題不難,但是想做出來還得動動腦子;
#include<iostream>
#include<cstdio>
#include<cstring>
#define INF 0x3f3f3f3f
using namespace std;
int v,n,a[2005];
int dp[4005][4005];
int main()
{
scanf("%d",&n);
v=0;
memset(dp,0,sizeof(dp));
dp[0][0]=1;
for(int i=0; i<n; i++)
{
scanf("%d",&a[i]);
v+=a[i];
}
for(int i=0; i<n; i++) //用dp[i][j]存的是雙塔能不能達到;
{
for(int j=v; j>=0; j--)
{
for(int k=v; k>=0; k--)
{
if(dp[j][k])
{
dp[j+a[i]][k]=1;
dp[j][k+a[i]]=1;
}
}
}
}
bool flag=false;
for(int i=v; i>0; i--)
{
if(dp[i][i])
{
flag=true;
printf("%d\n",i);
break;
}
}
if(!flag) printf("Impossible\n");
return 0;
}