完美串 (DP)

传送门

中文题。

可以想到当只有一个字符那么最少要添加1个,两个连续不相等的字符不需要添加。

可以设dp[i][j]代表从i到j最少需要添加几个。

分为两种情况:当 s[i] == s[j] 的时候,那么一定需要添加一个,可以在i的左边 也可以在j的右边,如果在i的左边加 那就是dp[i][j-1] + 1,添加的那个字符就是和s[j]相反的。

如果在j的右边加 那就是dp[i+1][j] + 1,添加的字符与s[i]相反。当然dp[i][j]取二者的较小值。

当s[i] != s[j]的时候,除了要算出以上的两种方案 还需要比较与 dp[i+1][j-1]的大小。

#include <algorithm>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <iostream>
#define MAX 0x3f3f3f3f
#define N 2000
#define mod 1000000007
typedef long long LL;
using namespace std;
const double pi = acos(-1.0);

int n;
char s[N];
int dp[N][N], a[N];

int main()
{
    int T; cin >> T;
    while(T--) {

        cin >> n >> s + 1;
        memset(a, 0, sizeof(a));
        for(int i = 1; i <= n; i++) if(s[i] == '1') a[i] = 1;

        memset(dp, MAX, sizeof(dp));
        for(int i = 1; i <= n; i++) dp[i][i] = 1, dp[i][i-1] = 0; // 注意初始化 dp[i][i-1] = 0; 也就是两个连续不相同的是不要添加字符的 WA了一次。。

        for(int j = 2; j <= n; j++) {
            for(int i = j-1; i >= 1; i--) {
                dp[i][j] = min(dp[i+1][j], dp[i][j-1]) + 1;
                if(a[i] != a[j]) dp[i][j] = min(dp[i][j], dp[i+1][j-1]);
            }
        }
        cout << dp[1][n] << endl;
    }
	return 0;
}
时间: 2024-08-28 08:11:41

完美串 (DP)的相关文章

完美串(区间dp)

完美串 Description 爱美之心人皆有之,GG也不例外.所以GG他对于完美串有一种热衷的爱.在GG眼中完美串是一个具有无比魅力的01子串.这个子串有之其魅力之处,对它取反后水平翻转,它又和它原来的一模一样.这就是GG热爱它的原因.但是世上并不是所有的01串都是完美串,所以GG下定决心想改造01串,使所有的01串都成为完美串.但是改造01串是一个巨大的工程,GG太忙了,他还差T个01串未改造,他需要你的帮助.而你只需要告诉它至少添加几个'0','1'字符就可以使得01串成为完美串. Inp

51nod1313 完美串

一个N长的字符串S(N<=3000),只由'R','G','B'三种字符组成,即串中不存在除了这3个字符以外的其他字符.字符串S的子串substr(L,R)指S[L]S[L+1]S[L+2]..S[R]构成的字符串,其中0<=L<=R<N.称一个字符串为“完美串”,当且仅当该串中存在K个连续的'G'字符.问,存在多少个不同的四元组(a,b,c,d)满足substr(a,b)+substr(c,d)是完美串,其中,0 <= a <= b < c <= d &l

广工校赛——LCS——完美串

Description 爱美之心人皆有之,GG也不例外.所以GG他对于完美串有一种热衷的爱.在GG眼中完美串是一个具有无比魅力的01子串.这个子串有之其魅力之处,对它取反后水平翻转,它又和它原来的一模一样.这就是GG热爱它的原因.但是世上并不是所有的01串都是完美串,所以GG下定决心想改造01串,使所有的01串都成为完美串.但是改造01串是一个巨大的工程,GG太忙了,他还差T个01串未改造,他需要你的帮助.而你只需要告诉它至少添加几个'0','1'字符就可以使得01串成为完美串. Input 有

URAL1081——DP—— Binary Lexicographic Sequence

Description Consider all the sequences with length (0 <  N < 44), containing only the elements 0 and 1, and no two ones are adjacent (110 is not a valid sequence of length 3, 0101 is a valid sequence of length 4). Write a program which finds the seq

fzu2172 字符串dp

F - 巡了南山我巡北山 Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status Practice FZU 2172 Description 大师兄在取经途中迷上了ACM-ICPC,稍不留神,师傅就被妖怪抓走了. 大师兄并不着急去救师傅,在虐这道简单题: 有两个字符串A和B,每一次可以选择以下操作中的一种,只对字符串A进行操作,用最少的操作使得字符串A与字符串B相等: 在

Palindrome(POJ 1159 DP)

Palindrome Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 58168   Accepted: 20180 Description A palindrome is a symmetrical string, that is, a string read identically from left to right as well as from right to left. You are to write a

CodeForces 176B Word Cut (计数DP)

Word Cut Time Limit:2000MS     Memory Limit:262144KB     64bit IO Format:%I64d & %I64u Submit Status Practice CodeForces 176B Description Let's consider one interesting word game. In this game you should transform one word into another through specia

Codeforces 611D New Year and Ancient Prophecy DP

题意: 把一个字符串分割成多个小串,小串组成严格递增序列,n<=5000 这是一个DP. s代表原串 dp[i][j]代表当前到i位置最后一个串是以j为开头的方案数.答案就是dp[n][1]+...+dp[n][n] 很容易得到dp[i][j]=dp[j-1][k]+dp[j-1][k+1]……dp[j-1][j-1]    (i-j=j-k) 如果s[k-1....j-1] >=s[j....i], dp[i][j]+=dp[j-1][k-1] 这样dp的递推式就有了,很容易发现dp[i][

[CF245H] Queries for Number of Palindromes (容斥原理dp计数)

题目链接:http://codeforces.com/problemset/problem/245/H 题目大意:给你一个字符串s,对于每次查询,输入为一个数对(i,j),输出s[i..j]之间回文串的个数. 容斥原理: dp[i][j] = dp[i+1][j]+dp[i][j-1]-dp[i+1][j-1]; if( str[i]==str[j] 并且 str[i+1..j-1]是回文串 ) dp[i][j]++; 代码: 1 #include <cstdio> 2 #include &l