您的位置:首页 > 其它

搭建双塔 DP问题

2018-02-07 17:04 120 查看


描述

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
Copy


样例输出1

7
Copy


来源

某校NOIP模拟题

dp[i][j]表示对于前i个物体,构成差值为j是的塔高。我们默认记录的是高塔

有四种情况。对于当前插值为j,物体为i。

如果差值j大于物体高度,我们必须放到高塔上,才能保证达到差值j。所以dp[i-1][j-a[i]]+a[i];

如果差值j小于物体高度,我们要放到小塔上,并使得小塔变成大塔,使的高度差为j。 那么就是我们要找一个 dp[i
- 1][a[i] - j] + j

第三种情况就是直接放到小塔上,似的插值为j。dp[i][j] = max(dp[i][j],
dp[i - 1][j + a[i]]);

最后就是不放   dp[i][j] = max(dp[i][j], dp[i - 1][j]);

#include<iostream>

#include<cstdio>

#include<cstring>

#include<queue>

#include<algorithm>

#include <fstream>

#include<vector>

#include<math.h>

using namespace std;

int dp[1000][1000];

int a[1100];

int main()

{

     int n;

    cin >> n;

    for (int i = 1; i <= n; ++i)

    {

        cin >> a[i];

    }

    memset(dp, -0x3f, sizeof dp);

    dp[0][0] = 0;//dp[i][j]表示前i个木块组成的双子塔的差值为j时的长度

    for (int i = 1; i <= n; ++i)//对于当前木块

    {

        for (int j = 0; j <= 2000; ++j) //形成j的差值

        {

            if (j >= a[i])//如果我们想要形成的插值大于当前木块长度,那肯定是往高的那个塔放

            {

                dp[i][j] = max(dp[i][j], dp[i - 1][j - a[i]] + a[i]); //放去高的上头.

            }

            if (a[i] >= j) //如果小于,我们放到小的上头并使小的变得高的,插值为j

            {   //我们本来A小B大,AB差值为a【i】-j.我们想要插值为j

                dp[i][j] = max(dp[i][j], dp[i - 1][a[i] - j] + j);

            }

            dp[i][j] = max(dp[i][j], dp[i - 1][j + a[i]]); //放在小的那里

            dp[i][j] = max(dp[i][j], dp[i - 1][j]); //不用

        }

    }

    if (dp
[0] <= 0) {

        cout << "Impossible" << endl;

    }

     else

        cout << dp
[0] << endl;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: