现在的位置: 首页 > 综合 > 正文

UVA 11552 DP水题

2013年10月10日 ⁄ 综合 ⁄ 共 1159字 ⁄ 字号 评论关闭

刘汝佳大牛胖胖白书第四道DP基础练习题

这道题WA了三发

还是精神不够集中,都是不该错的小逻辑

要学会找好状态

DP[i][j]:第i组以j字幕结尾时最小的快数,j字母不在的话就标0

然后搜索DP[n]中的所有非零值取最小

以后做DP记得写转移方程,无论它有多简单(虽然对我这个菜鸟来说没有简单题)

#include <cstdio>
#include <cstring>
#include <algorithm>
#define MAX 1100
#define maxn 20000
using namespace std;
char s1[MAX];

int DP[1100][30], temp[30];
int k;
int main()
{
    //freopen("1.txt", "r", stdin);
    int t, dp0, it, ans;
    scanf("%d", &t);
    while(scanf("%d%s", &k, s1 + 1) != EOF)
    {
        dp0 = 0; ans = maxn;
        memset(temp, 0, sizeof(temp));
        memset(DP, 0, sizeof(DP));
        int len = strlen(s1 + 1); int n = len / k;
        for(int i = 1; i <= k; i++) temp[s1[i] - 'a']++;
        for(int i = 0; i <= 25; i++) if(temp[i]) dp0++;
        for(int i = 0; i <= 25; i++) if(temp[i]) DP[1][i] = dp0;
        for(int i = 2; i <= n; i++)
        {
            memset(temp, 0, sizeof(temp)); dp0 = 0;
            for(int j = (i - 1) * k + 1; j <= i * k; j++) temp[s1[j] - 'a']++;
            for(int j = 0; j <= 25; j++) if(temp[j]) {dp0++; it = j;}
            if(dp0 == 1)
            {
                DP[i][it] = maxn;
                for(int j = 0; j <= 25; j++)
                    if(DP[i - 1][j]) DP[i][it] = min(DP[i][it], j == it ? DP[i - 1][j] : DP[i - 1][j] + 1);

                continue;
            }
            else
            {
                for(int j = 0; j <= 25; j++)
                if(temp[j])
                {
                    DP[i][j] = maxn;
                    for(int k = 0; k <= 25; k++)
                    if(DP[i - 1][k] && temp[k] && k != j) DP[i][j] = min(DP[i][j], DP[i - 1][k] + dp0 - 1);
                    else if(DP[i - 1][k]) DP[i][j] = min(DP[i][j], DP[i - 1][k] + dp0);
                }
            }
        }
        for(int i = 0; i <= 25; i++) if(DP[n][i]) ans = min(ans, DP[n][i]);
        printf("%d\n", ans);
    }
}

抱歉!评论已关闭.