• UVAlive-3363 String Compression


    题目大意:

    给你一个字符串,让你把它压缩,比如gogogo可以压缩成3(go),letsgogogoletsgogogo可以压缩成2(lets3(go)),然后问你压缩后的最短长度。

    解题思路:

    区间DP。

    一开始我以为是个基础的DP。没想到在第二个样例过不去,才发现这不是个基础的DP,也不是...这应该算是基础的区间DP吧。

    首先设dp[i][j]表示从i到j这个区间内的字符串能压缩的最短长度。

    那么状态转移方程就是

    dp[i][j] = min(dp[i][k] + dp[k+1][j], dp[i][i+a] + 2 + len(a));

    q其中k是[i,j]区间内的任意整数点,a是将字符串i到j的子串缩成长度为a的字符串的长度。

    代码:

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    
    const int maxn = 205;
    const int INF = 0x3f3f3f3f;
    
    char str[maxn];
    int dp[maxn][maxn];
    
    int check(int be, int en, int k) {
    	if ((en - be + 1) % k) return 0;
    	for (int i = be + k; i <= en; i += k)
    		for (int j = 0; j < k; ++j)
    			if (str[i + j] != str[be + j]) return 0;
    	return (en - be + 1) / k;
    }
    int getNum(int x) {
    	if (x >= 0 && x <= 9) return 1;
    	else if (x >= 10 && x <= 99) return 2;
    	else return 3;
    }
    int main() {
    	int t;
    	scanf("%d", &t);
    	while (t--) {
    		scanf(" %s", str);
    		int tmp, len = strlen(str);
    
    		for (int i = 0; i < len; ++i) dp[i][i] = 1;
    		for (int i = 0; i < len; ++i) {
    			for (int j = i - 1; j >= 0; --j) {
    				dp[j][i] = INF;
    				for (int k = j; k < i; ++k)
    					dp[j][i] = min(dp[j][i], dp[j][k] + dp[k+1][i]);
    				for (int k = 1; k <= (i - j + 1) / 2; ++k) {
    					int tmp = check(j, i, k);
    					if (tmp)
    						dp[j][i] = min(dp[j][i], dp[j][j + k - 1] + 2 + getNum(tmp));
    				}
    			}
    		}
    		printf("%d
    ", dp[0][len-1]);
    	}
    	return 0;
    }


  • 相关阅读:
    2月4日进度
    每日总结3-6
    每日总结3-5
    每日总结3-4
    每日总结3-2
    本周计划
    本周计划
    假期每日总结2-13
    假期每日总结2-12
    假期每日总结2-11
  • 原文地址:https://www.cnblogs.com/wiklvrain/p/8179365.html
Copyright © 2020-2023  润新知