IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    BZOJ1032:[JSOI2007]祖码Zuma dp

    wyfcyx发表于 2015-03-06 14:17:48
    love 0

    思路:

    首先将颜色分段.

    令\(f[i][j]\)表示第\(i\)段到第\(j\)段全部清除最小的代价.

    转移一:

    \[f[i][j]=\min_{k=i}^{j-1}f[i][k]+f[k+1][j]\]

    转移二:

    \(i=j\),直接转移

    转移三:

    \(col[i]=col[j]\),\(f[i][j]=f[i+1][j-1]+blabla...\)

    可是这样是不一定对的.

    (做到这里在OJ上就可以AC了.)

    他不能处理三个离散的珠子合并的情况.

    比如1 2 2 1 3 3 1.

    正确答案应该是2.

    我们加一步判断,如果区间两端都是只有一个的话,尝试在区间中寻找同样颜色的,然后合并.

    由于数据问题,这样判断是会WA的.但是这应该是正确答案.

    (在OJ上可以AC的代码)

    #include
    #include
    #include
    #include
    #include
    using namespace std;
     
    #define N 510
    int a[N],col[N],cnt[N],id;
     
    int f[N][N];
    int main(){
        int n;scanf("%d",&n;);
        register int i,j,k,p;
        for(i=1;i<=n;++i)scanf("%d",&a;[i]);
        for(i=1;i<=n;){
            col[++id]=a[i],cnt[id]=1;
            for(j=i;j!=n&&a;[j]==a[j+1];++j,++cnt[id]);
            i=j+1;
        }
         
        for(k=1;k<=id;++k){
            for(i=1;i+k-1<=id;++i){
                j=i+k-1;
                if(i==j)f[i][j]=(cnt[i]>=3?1:(3-cnt[i]));
                else{
                    f[i][j]=~0U>>1;
                    for(p=i;p=3&&col;[i]==col[j])f[i][j]=min(f[i][j],f[i+1][j-1]+((cnt[i]+cnt[j]>=3)?0:(3-cnt[i]-cnt[j])));
                }
            }
        }
         
        printf("%d\n",f[1][id]);
        return 0;
    }


沪ICP备19023445号-2号
友情链接