zoukankan      html  css  js  c++  java
  • SCOI2003 字符串折叠

    题目传送门

    (DP)的实现也要下一下功夫,比如这题,知道转移方程却不会实现


    定义f[i][j]为区间([i,j])折叠的最短长度
    然后就是区间(DP)的套路,枚举中间断点,然后转移

    如何判断能否折叠,以及折叠后的处理没有想到
    还要多加练习

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #define LL long long
    using namespace std;
    LL read() {
        LL k = 0, f = 1; char c = getchar();
        while(c < '0' || c > '9') {
            if(c == '-') f = -1;
            c = getchar();
        }
        while(c >= '0' && c <= '9')
          k = k * 10 + c - 48, c = getchar();
        return k * f;
    }
    int f[110][110]; char s[110];
    bool cmp(int x, int k, int y) { //判断能否折叠
        if(((y-x+1) % (k-x+1))) return false;
        int pos = x;
        for(int i = x; i <= y; ++i) {
            if(s[i] != s[pos++]) return false;
            if(pos > k) pos = x;
        }
        return true;
    }
    int calc(int x) { //折叠后的数字不一定只为个位数,要计算它的位数
        int num = 0;
        while(x) ++num, x /= 10;
        return num;
    }
    int main() {
        scanf("%s", s+1); int len = strlen(s+1);
        memset(f, 127/3, sizeof(f));
        for(int l = 0; l <= len; ++l)
            for(int i = 1; i <= len-l+1; ++i) {
                int j = i + l - 1; f[i][j] = l;
                for(int k = i; k < j; ++k) {
                    if(!cmp(i, k, j)) f[i][j] = min(f[i][j], f[i][k] + f[k+1][j]);
                    else f[i][j] = min(f[i][j], f[i][k] + 2 + calc(l/(k-i+1)));
                }
            }
        cout << f[1][len];
        return 0;
    }
    
  • 相关阅读:
    升级或安装 GNOME Shell
    安装eclipse for c/c++环境
    BT3入门之中文语言支持
    开始接触BT5-自动登录X界面
    标准流与序列化
    IO流
    Collection与Map容器
    常用类
    枚举与常用类
    异常处理机制
  • 原文地址:https://www.cnblogs.com/morslin/p/11855424.html
Copyright © 2011-2022 走看看