1. 程式人生 > >洛谷 P2423 雙塔

洛谷 P2423 雙塔

不知道 name std ios 多少 輸出 get -- 刷表法

題目描述

2001年9月11日,一場突發的災難將紐約世界貿易中心大廈夷為平地,Mr. F曾親眼目睹了這次災難。為了紀念“911”事件,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: 復制
5
1 3 4 5 2
輸出樣例#1: 復制
7

思路:設布爾數組dp[i][j]表示第一座塔高為i,第二座塔高為j的這種狀態存不存在(存在為1,不存在為0),然後我的方法比較暴力,卡著時過的。。
三重循環枚舉,類似於01背包的更新方法(這裏我用的是刷表法),我們可以記錄一下總高度,然後除以2再枚舉高度就行了。
 1
#include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<cmath> 6 #include<queue> 7 using namespace std; 8 const int H=2000+5; 9 const int N=100+5; 10 bool dp[H][H]; 11 int n; 12 inline int read() 13 { 14 int ret=0,f=1; 15 char
c=getchar(); 16 while(c<0||c>9) 17 {if(c==-) f=-1;c=getchar();} 18 while(c>=0&&c<=9) 19 {ret=ret*10+c-0;c=getchar();} 20 return ret*f; 21 } 22 int num[N]; 23 int main() 24 { 25 n=read(); 26 int sum=0; 27 for(int i=1;i<=n;i++) 28 { 29 num[i]=read(); 30 sum+=num[i]; 31 } 32 dp[0][0]=1; 33 for(int k=1;k<=n;k++) 34 { 35 for(int i=sum/2;i>=0;i--) 36 for(int j=sum/2;j>=0;j--) 37 { 38 if(dp[i][j]) 39 { 40 dp[i+num[k]][j]=1; 41 dp[i][j+num[k]]=1; 42 43 } 44 } 45 } 46 for(int i=sum/2;i>=1;i--) 47 { 48 if(dp[i][i]) {printf("%d\n",i);return 0;} 49 } 50 printf("Impossible\n"); 51 return 0; 52 }

 

洛谷 P2423 雙塔