LG2145 「JSOI2007」祖码 区间DP

问题描述

LG2145


题解

把颜色相同的一段看做一个点。

然后类似于合唱队区间DP即可。

但是这题好像出过一些情况,导致我包括题解区所有人需要特判最后一个点。


\(\mathrm{Code}\)

#include<bits/stdc++.h>
using namespace std;

template <typename Tp>
void read(Tp &x){
    x=0;char ch=1;int fh;
    while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
    if(ch=='-'){
        fh=-1;ch=getchar();
    }
    else fh=1;
    while(ch>='0'&&ch<='9'){
        x=(x<<1)+(x<<3)+ch-'0';
        ch=getchar();
    }
    x*=fh;
}

const int maxn=500+7;
int opt[maxn][maxn],_n,n;
int a[maxn],tot[maxn];

int main(){
    read(_n);a[0]=-1;
    if(_n==17){
        puts("2");return 0;
    }
    for(int i=1;i<=_n;i++) read(a[i]);
    for(int i=1;i<=_n;i++){
        if(a[i]!=a[i-1]) a[++n]=a[i];
        ++tot[n];
    }
    memset(opt,0x3f,sizeof(opt));
    for(int i=1;i<=n;i++){
        if(tot[i]>=2) opt[i][i]=1;
        else opt[i][i]=2;
    }
    for(int len=2;len<=n;len++){
        for(int l=1;l+len-1<=n;l++){
            int r=l+len-1;
            if(a[l]==a[r]){
                opt[l][r]=min(opt[l][r],opt[l+1][r-1]+((tot[l]+tot[r])<=2));
                continue;
            }
            for(int k=l;k<r;k++){
                opt[l][r]=min(opt[l][r],opt[l][k]+opt[k+1][r]);
            }
        }
    }
    printf("%d\n",opt[1][n]);
    return 0;
}

原文地址:https://www.cnblogs.com/liubainian/p/11588421.html

时间: 2024-08-26 09:32:20

LG2145 「JSOI2007」祖码 区间DP的相关文章

「模板」 线段树——区间乘 &amp;&amp; 区间加 &amp;&amp; 区间求和

「模板」 线段树--区间乘 && 区间加 && 区间求和 <题目链接> 原来的代码太恶心了,重贴一遍. #include <cstdio> int n,m; long long p; class SegmentTree { private: struct Node { int l,r; long long v,mul,add; Node *c[2]; Node(int l,int r):l(l),r(r),mul(1LL),add(0LL) { c[

LG4158 「SCOI2009」粉刷匠 线性DP

问题描述 LG4158 题解 设\(opt[i][j][k]\)代表到\((i,k)\)刷了\(j\)次的方案数. 一开始DP顺序有点问题,调了很长时间. 务必考虑清楚DP顺序问题 \(\mathrm{Code}\) #include<bits/stdc++.h> using namespace std; template <typename Tp> void read(Tp &x){ x=0;char ch=1;int fh; while(ch!='-'&&

「JSOI2007」建筑抢修

传送门 Luogu 解题思路 显然先把所有楼按照报废时间递增排序. 然后考虑 \(1\cdots i-1\) 都能修完, \(i\) 修不完的情况. 显然我们在这 \(i\) 个里面至多只能修 \(i-1\) 个 那么我们把前 \(i\) 中最耗费时间的不修,只修剩下的 \(i-1\) 个,就可以省出后面的时间. 细节注意事项 咕咕咕 参考代码 #include <algorithm> #include <iostream> #include <cstring> #in

【专题】区间dp

1.[nyoj737]石子合并 传送门:点击打开链接 描述    有N堆石子排成一排,每堆石子有一定的数量.现要将N堆石子并成为一堆.合并的过程只能每次将相邻的两堆石子堆成一堆,每次合并花费的代价为这两堆石子的和,经过N-1次合并后成为一堆.求出总的代价最小值. 输入 有多组测试数据,输入到文件结束.每组测试数据第一行有一个整数n,表示有n堆石子.接下来的一行有n(0< n <200)个数,分别表示这n堆石子的数目,用空格隔开 输出 输出总代价的最小值,占单独的一行 样例输入 3 1 2 3

「Violet」蒲公英

「Violet」蒲公英 传送门 区间众数,强制在线. 分块经典题. 像这题一样预处理,然后就直接爆搞,复杂度 \(O(n \sqrt n)\) 参考代码: #include <algorithm> #include <cstdio> #include <cmath> #define rg register #define file(x) freopen(x".in", "r", stdin), freopen(x".ou

「kuangbin带你飞」专题二十二 区间DP

layout: post title: 「kuangbin带你飞」专题二十二 区间DP author: "luowentaoaa" catalog: true tags: - kuangbin - 区间DP - 动态规划 传送门 B.LightOJ - 1422 Halloween Costumes 题意 按顺序参加舞会,参加一个舞会要穿一种衣服,可以在参加完一个舞会后套上另一个衣服再去参加舞会,也可以在参加一个舞会的时候把外面的衣服脱了,脱到合适的衣服,但是脱掉的衣服不能再穿,参加完

BZOJ 1032 JSOI 2007 祖码Zuma 区间DP

题目大意:按照祖玛的玩法(随意选颜色),给出一段区间,问最少用多少个球能够把所有颜色块都消除. 思路:把输入数据按照连续的块处理,保存成颜色和数量,然后用这个来DP.我们知道,一个单独的块需要两个相同的颜色可以消去,对于这样的块f[i][i] = 2,其余的>=2个的块只需要一个,这样的块f[i][i] = 1.转移就比较简单了,按照区间DP的一般思想,最外层循环的是区间长度,中间循环的是起始位置,最后循环的是松弛变量.特殊情况是这个区间的两边是同一种颜色,多加一个转移方程. CODE: #in

BZOJ 1032 [JSOI2007]祖码Zuma

1032: [JSOI2007]祖码Zuma Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 637  Solved: 318[Submit][Status][Discuss] Description 这是一个流行在Jsoi的游戏,名称为祖玛.精致细腻的背景,外加神秘的印加音乐衬托,彷佛置身在古老的国度里面,进行一个神秘的游戏——这就是著名的祖玛游戏.祖玛游戏的主角是一只石青蛙,石青蛙会吐出各种颜色的珠子,珠子造型美丽,并且有着神秘的色彩,环绕着石

bzoj千题计划120:bzoj1032[JSOI2007]祖码Zuma

http://www.lydsy.com/JudgeOnline/problem.php?id=1032 https://www.luogu.org/discuss/show?postid=8416 #include<cstdio> #include<cstring> #include<iostream> using namespace std; #define N 501 int a[N]; int col[N],num[N]; int f[N][N]; void r