• UVA11552------FEWEST FLOPS------区间型的DP


    题目地址:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2547

    题目意思:

    给你一个字符串,长度为k的整数倍,要你分成每个长度的段

    每个段内可以重新编排

    连续的几个字母看作一个块

    问最少有几个块

    解题思路:

    对于每个段来说,我们可以知道最少的块,即里面有几种字母,记为chunk[i]

    我们设f[i][j]为第i段的第j位放在最末尾时的最少块数

    则针对第i-1块的第l个放在末尾时来说

    如果和第i的第一个相同,则可以合并一个块,则

    f[i][j] = min(f[i][j],f[i-1][l]+chunk-1);

    否则

    f[i][j] = min(f[i][j],f[i-1][l]+chunk);

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    
    const int maxn = 1010;
    
    int f[maxn][maxn];
    char s[maxn];
    bool vis[maxn];
    
    int main()
    {
        int t;
        scanf("%d",&t);
        while(t--)
        {
            int k,len;
            scanf("%d",&k);
            scanf("%s",s);
            len = strlen(s);
            memset(f,0x3f3f3f3f,sizeof(f));
            for(int i=1;i<=len/k;i++)
            {
                memset(vis,false,sizeof(vis));
                for(int j=1;j<=k;j++)
                {
                    vis[s[(i-1)*k+j-1]] = true;
                }
                int chunk = 0;
                for(int j='a';j<='z';j++)
                    if(vis[j])
                        chunk++;
                if(i==1)
                {
                    for(int j=1;j<=k;j++)
                        f[1][j] = chunk;
                    continue;
                }
    
                for(int j=1;j<=k;j++)
                {
                    int rear = (i-1)*k+j-1;
                    for(int l=1;l<=k;l++)
                    {
                        int pre = (i-2)*k+l-1;
                        if(vis[s[pre]] && (chunk==1 || s[pre]!=s[rear]))
                            f[i][j] = min(f[i][j],f[i-1][l]+chunk-1);
                        else
                            f[i][j] = min(f[i][j],f[i-1][l]+chunk);
                    }
                }
            }
    
            int ans = 0x3f3f3f3f;
            for(int i=1;i<=k;i++)
                ans = min(ans,f[len/k][i]);
            printf("%d
    ",ans);
        }
        return 0;
    }
    
    
    
    



  • 相关阅读:
    ubuntu 更新软件
    如何在linux(lubuntu)下搭建C/C++开发环境
    Linux下如何查看版本信息
    知识点笔记
    Require.js中使用jQuery 插件
    async中常用总结
    node.js在遇到“循环+异步”时的注意事项
    前端性能优化
    生产/消费者问题
    线程与内存
  • 原文地址:https://www.cnblogs.com/riskyer/p/3270912.html
Copyright © 2020-2023  润新知