• BZOJ 1090 字符串折叠


    n^3dp。貌似写麻烦了。。。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define maxn 105
    #define inf 2000000000
    using namespace std;
    int rols[maxn][maxn],dp[maxn][maxn],n,nxt[maxn];
    char s[maxn],p[maxn];
    int kmp(int l,int r)
    {
        for (int i=l;i<=r;i++) p[i-l]=s[i];
        memset(nxt,0,sizeof(nxt));int cnt=0;
        for (int i=2;i<=r-l+1;i++)
        {
            while ((cnt) && (p[cnt]!=p[i-1]))
                cnt=nxt[cnt];
            if (p[cnt]==p[i-1]) cnt++;
            nxt[i]=cnt;
        }
        if (!nxt[r-l+1]) return 0;
        if ((r-l+1)%((r-l+1)-nxt[(r-l+1)])) return 0;
        return (r-l+1)-nxt[r-l+1];
    }
    int calc(int x)
    {
        int ret=0;
        while (x) 
        {
            ret++;
            x/=10;
        }
        return ret;
    }
    int main()
    {
        scanf("%s",s);n=strlen(s);
        for (int i=n;i>=1;i--) s[i]=s[i-1];
        for (int i=1;i<=n;i++)
            for (int j=i;j<=n;j++)
                rols[i][j]=kmp(i,j);
        for (int i=1;i<=n;i++) dp[i][i]=1;
        for (int i=2;i<=n;i++)
            for (int j=1;j<=n-i+1;j++)
            {
                dp[j][i+j-1]=inf;
                for (int k=j;k<=i+j-2;k++)
                    dp[j][i+j-1]=min(dp[j][i+j-1],dp[j][k]+dp[k+1][i+j-1]);
                if (rols[j][i+j-1]) dp[j][i+j-1]=min(dp[j][i+j-1],calc(i/rols[j][i+j-1])+2+dp[j][j+rols[j][i+j-1]-1]);
            }    
        printf("%d
    ",dp[1][n]);
        return 0;
    }
  • 相关阅读:
    设计模式浅谈
    链表的遍历(1)
    链表的删除(3)
    链表结构的反转(5)
    二叉树数组表示法
    循环链表的插入和删除
    链表的链接(2)
    双向链表内结点的删除(4)
    hdu1042
    数组和链表的区别
  • 原文地址:https://www.cnblogs.com/ziliuziliu/p/6014348.html
Copyright © 2020-2023  润新知