又是一个思路很奇妙的题(最近我看什么DP题都觉得很奇妙)。

先看题:

洛谷P1651 塔

题目描述

小明很喜欢摆积木,现在他正在玩的积木是由 N 个木块组成的,他想用这些木块搭出两座高度相同的塔,一座塔的高度是搭建它的所有木块的高度和,并且一座塔至少要用一个木块。每个木块只能用一次,也可以不用。目前已知每块木块的高度,小明想知道在最终两个塔的高度相同的情况下,他所能搭的塔的最大高度是多少,你能帮助他吗?

输入格式

第一行为一个整数 N,表示木块个数。

第二行是 N 个整数,表示 N 块木块的高度。

输出格式

仅一个整数,表示能搭建的塔的最大高度,若不能搭建两座相同高度的塔,则输出 -1

输入输出样例

输入 #1
3
2 3 5
输出 #1
5

说明/提示

对于 100% 的数据,N50 ,每块木块的高度 h 满足 1h500000,所有木块的高度总和 500000。

我是用了一个结构体:

struct node{
    int a,b;//a是两塔中较高的塔的高度,b是另一个塔的高度。
    bool p;//p表示两塔高度差能不能为i。
}f[500010];//f[i]中i是两塔高度差。

i从1到n,放第i块积木,放每一块积木最多有三种可能情况:

1.积木放在a塔。

2.积木放在b塔,但b塔高度超不过a塔。

3.积木放在b塔,且b塔高度会超过a塔。(a、b塔要交换位置)

枚举新的塔的高度差,是由之前的哪种情况得到,求a塔最高值,在将这一轮的和总的进行比较,所有的都取a塔的更大值。

最后看f[0].a是否有高度,有则输出f[0].a,否则输出-1。

下面是代码:

#include<iostream>
using namespace std;
int n;
int h[60];
struct node{
    int a,b;
    bool p;
}f[500010],t[500010];
int qian[500010];
int main(){
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>h[i];
        qian[i]=qian[i-1]+h[i];
    }
    f[0].p=1;
    for(int i=1;i<=n;i++){
        for(int j=0;j<=qian[i];j++){
            if(h[i]>j){
                if(f[h[i]-j].p){                    
                    t[j].a=f[h[i]-j].b+h[i];
                    t[j].b=f[h[i]-j].a;
                    t[j].p=1;
                }
            }
            else{
                if(f[j-h[i]].p){
                    t[j].a=f[j-h[i]].a+h[i];
                    t[j].b=f[j-h[i]].b;
                    t[j].p=1;
                }
            }
            if(f[j+h[i]].p){
                if(t[j].p==0){
                    t[j].a=f[j+h[i]].a;
                    t[j].b=f[j+h[i]].b+h[i];
                    t[j].p=1;
                }
                else if(t[j].a<f[j+h[i]].a){
                    t[j].a=f[j+h[i]].a;
                    t[j].b=f[j+h[i]].b+h[i];
                    t[j].p=1;
                }
            }
        }
        for(int j=0;j<=qian[i];j++){
            if(t[j].a>f[j].a&&t[j].p){
                f[j]=t[j];
            }
            t[j].p=0;
        }
    }
    if(f[0].a==0){
        cout<<-1;
        return 0;
    }
    cout<<f[0].a;
    return 0;
}

 

posted @ 2022-03-24 17:02  zzzzzz2  阅读(102)  评论(0编辑  收藏  举报