字符串DP*2

P2246 SAC#1 - Hello World(升级版)

题目背景

T1答案要mod1000000007(10^9+7),请重新提交,非常抱歉!

一天,智障的pipapi正在看某辣鸡讲义学程序设计。

题目描述

在讲义的某一面,他看见了一篇文章。这篇文章由英文字母(大小写均有)、数字、和空白字符(制表/空格/回车)构成。

pipapi想起了他最近刚刚学会写的Hello World程序。他非常好奇,这篇文章中,“HelloWorld”作为子序列到底出现过多少次呢?

由于papapi是个智障,大小写对于他而言毫无区别;因此,“hEllOWorLD”这样的子序列也是可以接受的。O和W之间的空格是也是可以少的;也就是说,“HelloWorld”是可以的。根据标程的意思,就是没有空格,不用考虑空格的情况。

两个子序列相同当且仅当它们每一个字符所在的位置都相同。

由于答案可能很大,请输出结果对1000000007(10^9+7)的余数。

输入输出格式

输入格式:

输入包含若干行。这些行的内容共同构成一篇文章。

文章以EOF(文件结尾)结束。

输出格式:

输出仅包含一个整数,表示这篇文章中“Hello World”出现的次数。 d

输入输出样例

输入样例#1: 
HhEeLlLlOoWwOoRrLlDd
输出样例#1: 
1536
输入样例#2: 
Gou Li Guo Jia Sheng Si Yi
Qi Yin Huo Fu Bi Qu Zhi
River can feed people
Also can race boats
Hall Ellen Ok Words locked 
输出样例#2: 
273

说明

记n为输入的文章的长度(字符数)。

对于20%的数据,n <= 20。

对于50%的数据,n <= 500。

对于所有的数据,15 <= n <= 500000。

————————————————————————————————————————————

挺水的字符串DP,思路还是不错的

code

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
using namespace std;

typedef long long LL;
const int MOD = 1e9 + 7;
char ch1[233] = "#helloworld";
char ch2[233] = "#HELLOWORLD";
int f[233];

int main() {
    char x; f[0] = 1;
    while ((x = getchar())!=EOF) 
        for (int i = 10; i >= 1; -- i) 
            if (x == ch1[i] || x == ch2[i]) 
                f[i] = (f[i-1] + f[i]) % MOD;
    cout << f[10] << endl;
    return 0;
}

P2890 [USACO07OPEN]便宜的回文Cheapest Palindrome

题目描述

Keeping track of all the cows can be a tricky task so Farmer John has installed a system to automate it. He has installed on each cow an electronic ID tag that the system will read as the cows pass by a scanner. Each ID tag's contents are currently a single string with length M (1 ≤ M ≤ 2,000) characters drawn from an alphabet of N (1 ≤ N ≤ 26) different symbols (namely, the lower-case roman alphabet).

Cows, being the mischievous creatures they are, sometimes try to spoof the system by walking backwards. While a cow whose ID is "abcba" would read the same no matter which direction the she walks, a cow with the ID "abcb" can potentially register as two different IDs ("abcb" and "bcba").

FJ would like to change the cows's ID tags so they read the same no matter which direction the cow walks by. For example, "abcb" can be changed by adding "a" at the end to form "abcba" so that the ID is palindromic (reads the same forwards and backwards). Some other ways to change the ID to be palindromic are include adding the three letters "bcb" to the begining to yield the ID "bcbabcb" or removing the letter "a" to yield the ID "bcb". One can add or remove characters at any location in the string yielding a string longer or shorter than the original string.

Unfortunately as the ID tags are electronic, each character insertion or deletion has a cost (0 ≤ cost ≤ 10,000) which varies depending on exactly which character value to be added or deleted. Given the content of a cow's ID tag and the cost of inserting or deleting each of the alphabet's characters, find the minimum cost to change the ID tag so it satisfies FJ's requirements. An empty ID tag is considered to satisfy the requirements of reading the same forward and backward. Only letters with associated costs can be added to a string.

字串S长M,由N个小写字母构成。欲通过增删字母将其变为回文串,增删特定字母花费不同,求最小花费。

输入输出格式

输入格式:

Line 1: Two space-separated integers: N and M

Line 2: This line contains exactly M characters which constitute the initial ID string

Lines 3..N+2: Each line contains three space-separated entities: a character of the input alphabet and two integers which are respectively the cost of adding and deleting that character.

输出格式:

Line 1: A single line with a single integer that is the minimum cost to change the given name tag.

输入输出样例

输入样例#1: 
3 4
abcb
a 1000 1100
b 350 700
c 200 800
输出样例#1: 
900

说明

If we insert an "a" on the end to get "abcba", the cost would be 1000. If we delete the "a" on the beginning to get "bcb", the cost would be 1100. If we insert "bcb" at the begining of the string, the cost would be 350 + 200 + 350 = 900, which is the minimum.

code

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
using namespace std;

const int MAXN = 2010;
int n, m;
int add[MAXN], del[MAXN], dp[MAXN][MAXN];
char t, ch[MAXN];

int main() {
    scanf("%d%d%s", &n, &m, &ch);
    for(int i = 1; i <= n; ++ i) {
        while (scanf("%c", &t) != EOF && (t == ' ' || t == '\n'));
        scanf("%d%d", &add[t], &del[t]);
    }
    int d1, d2;
    for (int r = 1; r < m; ++ r) {
        for (int l = r - 1; l >= 0; -- l) {
            if (ch[l] == ch[r]) dp[l][r] = dp[l + 1][r - 1];
            else {
                d1 = dp[l][r - 1] + min(del[ch[r]], add[ch[r]]);
                d2 = dp[l + 1][r] + min(del[ch[l]], add[ch[l]]);
                dp[l][r] = min(d1, d2);
            }
        }
    }
    printf("%d\n", dp[0][m - 1]);
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/hkttg/p/9385646.html