zoukankan      html  css  js  c++  java
  • Codeforces 137D

    D. Palindromes

    time limit per test 2 seconds
    memory limit per test 256 megabytes
    input standard input
    output standard output
    Friday is Polycarpus’ favourite day of the week. Not because it is followed by the weekend, but because the lessons on Friday are 2 IT lessons, 2 math lessons and 2 literature lessons. Of course, Polycarpus has prepared to all of them, unlike his buddy Innocentius. Innocentius spent all evening playing his favourite game Fur2 and didn’t have enough time to do the literature task. As Innocentius didn’t want to get an F, he decided to do the task and read the book called “Storm and Calm” during the IT and Math lessons (he never used to have problems with these subjects). When the IT teacher Mr. Watkins saw this, he decided to give Innocentius another task so that the boy concentrated more on the lesson and less — on the staff that has nothing to do with IT.

    Mr. Watkins said that a palindrome is a string that can be read the same way in either direction, from the left to the right and from the right to the left. A concatenation of strings a, b is a string ab that results from consecutive adding of string b to string a. Of course, Innocentius knew it all but the task was much harder than he could have imagined. Mr. Watkins asked change in the “Storm and Calm” the minimum number of characters so that the text of the book would also be a concatenation of no more than k palindromes. Innocentius can’t complete the task and therefore asks you to help him.

    Input

    The first input line contains a non-empty string s which is the text of “Storm and Calm” (without spaces). The length of the string s does not exceed 500 characters. String s consists of uppercase and lowercase Latin letters. The second line contains a single number k (1 ≤ k ≤ |s|, where |s| represents the length of the string s).

    Output

    Print on the first line the minimum number of changes that Innocentius will have to make. Print on the second line the string consisting of no more than k palindromes. Each palindrome should be non-empty and consist of uppercase and lowercase Latin letters. Use the character “+” (ASCII-code 43) to separate consecutive palindromes. If there exist several solutions, print any of them.

    The letters’ case does matter, that is an uppercase letter is not considered equivalent to the corresponding lowercase letter.

    Examples
    input
    abacaba
    1
    output
    0
    abacaba
    inputCopy
    abdcaba
    2
    output
    1
    abdcdba
    inputCopy
    abdcaba
    5
    output
    0
    a+b+d+c+aba
    input
    abacababababbcbabcd
    3
    output
    1
    abacaba+babab+bcbabcb

    题目大意:

    输入一个字符串和一个K值,输出将这个字符串拆成最多k个回文串的最小操作数,第二行输出修改后的回文串,有+分割。

    解题思路:

    开一个cost数组,预处理 i - j 区间改成回文串的最小操作数,状态转移:
    cost[i][j] = cost[i + 1][j - 1] + (a[i] != a[j])
    处理完后再处理一下dp i j,表示将前 j 个字符分割成 i 个部分最少需要多少操作,状态转移:
    dp[i][j] = min(dp[i - 1][l] + cost[l + 1][j], dp[i][j])
    之后就是分割路径了,设一个w数组表示分割点,
    dp[i - 1][j] != inf && dp[i][lt] == dp[i - 1][j] + cost[j + 1][lt]
    如果这个条件满足,则证明刚好从j + 1这个点分开,w存储的是分割点的下一个位置,然后根据w里存的值来修改字符串,修改好后按照w存的点输出 + 即可。

    Code:

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #include <cmath>
    #include <vector>
    #include <queue>
    #include <set>
    #include <map>
    using namespace std;
    const int mod = 1e9 + 7;
    const int N = 550;
    const int inf = 0x3f3f3f3f;
    typedef long long ll;
    int cost[N][N], dp[N][N];
    int w[N];
    int main()
    {
    	int k;
    	char a[N];
    	cin >> a + 1 >> k;
    	int n = strlen(a + 1);
    	memset(cost, 0, sizeof cost);
    	for (int i = 1; i <= n; i ++)//预处理区间修改最小值
    	  for (int j = 1; j <= i; j ++)
    	    cost[j][i] = cost[j + 1][i - 1] + (a[i] != a[j]);
    	memset(dp, 0x3f, sizeof dp);
    	dp[0][0] = 0;
    	for (int i = 1; i <= k; i ++)//前j个点分成i份最小操作数
    	{
    		for (int j = i; j <= n; j ++)
    		  for (int l = i - 1; l <= j; l ++)
    		    if (dp[i - 1][l] != inf)
    			  dp[i][j] = min(dp[i - 1][l] + cost[l + 1][j], dp[i][j]);
    	}
    	cout << dp[k][n] << endl;
    	int cnt = 0, lt = n;
    	for (int i = k; i >= 1; i --)//处理分割位置
    	{
    		for (int j = 1; j <= n; j ++)
    		{
    			if (dp[i - 1][j] != inf && dp[i][lt] == dp[i - 1][j] + cost[j + 1][lt])
    			{
    				w[i] = j + 1;
    				lt = j;
    				break;
    			}
    		}
    	}
    	w[k + 1] = n + 1;
    	w[1] = 1;
    	cnt = 1;
    	for (int i = 1; i <= k + 1; i ++)//去重
    	  if (w[i - 1] != w[i])
    	    w[cnt++] = w[i];
    	cnt -= 2;
    	w[cnt + 1] = n + 1;
    	for (int i = 1; i <= cnt; i ++)
    	{
    		int u = w[i], v = w[i + 1] - 1;//根据分好的点修改字符串
    		while (u < v)
    		{
    			a[v] = a[u];
    			u++, v--;
    		}
    	}
    	cnt = 2;
    	for (int i = 1; i <= n; i ++)
    	{
    		cout << a[i];
    		if (i == w[cnt] - 1)
    		{
    			if (w[cnt] != n + 1)  cout << '+';
    			cnt ++;
    		}
    	}
    	cout << endl;
    	return 0;
    }
    
  • 相关阅读:
    Android不规则瀑布流照片墙的实现+LruCache算法
    嵌入式OS入门笔记-以RTX为案例:六.RTX的任务调度
    Oracle backgroup processes
    Android中数据库的操作流程详解
    Dreamweaver PHP代码护眼配色方案
    Twitter 新一代流处理利器——Heron 论文笔记之Heron架构
    Docker简单介绍
    C#下使用GDAL
    Android:实现仿 美团/淘宝 多级分类菜单效果
    KVC在定义Model类中的妙用
  • 原文地址:https://www.cnblogs.com/Hayasaka/p/14294178.html
Copyright © 2011-2022 走看看