CodeForces1312E 区间DP

题意

伊珂丝是个爱玩游戏的少女。经常因为贪玩而耽误了咖啡馆的工作,也因此常被店长吐槽。不过真到了干活的时候,伊珂丝也是当仁不让的!

这次伊珂丝又来找店长PK了,如果店长赢下这局,伊珂丝就答应在咖啡馆里干一天活儿,你能帮帮店长,战胜伊珂丝吗?

游戏规则如下:

游戏中一开始有n个数字排成一排,这n(<=500)个数的大小都在1~1000之间。
每次可以选择两个 相邻且相等 的数字,将它们合并成一个数字。
合并后的数字是原来的数字 +1,合并后数字个数 -1。
如果没有满足合并条件的数,则游戏结束。最后剩下的数字越少越好。
现在给出n与这些数字的信息,你能帮助店长算一算,最好成绩是剩下几个数字?

解法

看数据范围和题意不难想到是区间DP,唯一值得讨论的是dp数组的维护形式,这里给出的形式是用一个node表示dp的节点,包含num(区间内元素数量), l(区间左值), r(区间右值),以num越小的node越优先来更新dp
tips:

  • 看似这样的表示方法不能唯一表示一个节点,形如 2 2 2的区间既可以表示为num = 2, l = 2, r = 3,也可以表示为num = 2, l = 3, r = 2,但是对于这道题来说不关键
  • 对于样例3 2 2 2而言,将由[1,3] + [4,4]来更新到全局,对于2 2 2 3而言,将有[1,1] + [2,4]来更新到全局,实际上总有一种区间合并的方式来更新到num最小的全局答案,与区间[2,2,2]计算的l,r是否唯一无关

代码

#include<bits/stdc++.h>
using namespace std;
#define PII pair<int,int>
#define fi first
#define se second
#define mp make_pair
#define LL long long
const int maxn = 500 + 10;
const int mod = 1e9 + 7; 
int N,M,S;
int a[maxn];
struct node {
    int l,r,num;
};
node dp[maxn][maxn];
int main(){
    int N; scanf("%d",&N);
    for(int i = 1; i <= N ; i ++) {
        for(int j = 1; j <= N; j ++) {
            dp[i][j].num = 0x3f3f3f3f;
        }
    }
    for(int i = 1; i <= N ; i ++) {
        scanf("%d", &a[i]);
        dp[i][i].num = 1;
        dp[i][i].l = dp[i][i].r = a[i];
    }
    for(int len = 1; len <= N; len ++) {
        for(int l = 1; l + len - 1 <= N; l ++) {
            int r = l + len - 1;
            for(int k = l ; k <= r - 1; k ++) {
                int num = dp[l][k].num + dp[k + 1][r].num;
                int L = dp[l][k].l,R = dp[k + 1][r].r;
                if(dp[l][k].r == dp[k + 1][r].l) {
                    num--;
                    if(dp[l][k].num == 1) L++;;
                    if(dp[k + 1][r].num == 1) R++;            
                }
                if(num < dp[l][r].num) {
                    dp[l][r].num = num;
                    dp[l][r].l = L;
                    dp[l][r].r = R;
                }    
            }
        }
    }
    printf("%d",dp[1][N].num);
    return 0;
}

// 5      4 3 2 1 1
// 9      4 3 2 1 1 2 3 4 5
posted @ 2020-10-03 15:05  Hugh_Locke  阅读(131)  评论(0编辑  收藏  举报