[luoguP2890] [USACO07OPEN]便宜的回文Cheapest Palindrome(DP)

Posted 蒟蒻zht的博客

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[luoguP2890] [USACO07OPEN]便宜的回文Cheapest Palindrome(DP)相关的知识,希望对你有一定的参考价值。

传送门

 

f[i][j] 表示区间 i 到 j 变为回文串所需最小费用

1.s[i] == s[j]  f[i][j] = f[i + 1][j - 1]

2.s[i] != s[j]  f[i][j] = min(f[i + 1][j] + cost[s[i]], f[i][j - 1] + cost[s[j]])

开头去掉一个字母和结尾增加一个字母的效果是一样的

所以 cost[s[i]] = min(add[s[i]], del[s[i]])

 

——代码

技术分享
 1 #include <cstdio>
 2 #include <cstring>
 3 #include <iostream>
 4 
 5 int n, m;
 6 int a[301], f[2010][2010];
 7 char s[2010];
 8 
 9 inline int read()
10 {
11     int x = 0, f = 1;
12     char ch = getchar();
13     for(; !isdigit(ch); ch = getchar()) if(ch == -) f = -1;
14     for(; isdigit(ch); ch = getchar()) x = (x << 1) + (x << 3) + ch - 0;
15     return x * f;
16 }
17 
18 inline int min(int x, int y)
19 {
20     return x < y ? x : y;
21 }
22 
23 inline int dp(int x, int y)
24 {
25     if(x >= y) return f[x][y] = 0;
26     if(f[x][y] ^ -1) return f[x][y];
27     if(s[x] == s[y]) return f[x][y] = dp(x + 1, y - 1);
28     else return f[x][y] = min(dp(x + 1, y) + a[s[x]], dp(x, y - 1) + a[s[y]]);
29 }
30 
31 int main()
32 {
33     int i;
34     char c[1];
35     n = read();
36     m = read();
37     scanf("%s", s + 1);
38     for(i = 1; i <= n; i++)
39     {
40         scanf("%s", c);
41         a[c[0]] = min(read(), read());
42     }
43     memset(f, -1, sizeof(f));
44     printf("%d\n", dp(1, m));
45     return 0;
46 }
View Code

 

以上是关于[luoguP2890] [USACO07OPEN]便宜的回文Cheapest Palindrome(DP)的主要内容,如果未能解决你的问题,请参考以下文章

[LuoguP3668][USACO17OPEN]现代艺术2

luoguP3147 [USACO16OPEN]262144

[luoguP3146] [USACO16OPEN]248(区间DP)

[luoguP3668] [USACO17OPEN]Modern Art 2 现代艺术2(栈)

[luoguP2948] [USACO09OPEN]滑雪课Ski Lessons(DP)

[luoguP2886] [USACO07NOV]牛继电器Cow Relays(矩阵)