搭建雙塔(Vijos-1037)

描述

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;
}


發佈了77 篇原創文章 · 獲贊 11 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章