跳过正文
  1. Posts/

poj 3280 Cheapest Palindrome (区间dp)

·2 分钟

poj 3280 题目链接

题意:一个字符串,给出添加一个字符或者删掉该字符的花费,问最小的话费使得字符串变成回文串。

思路:dp[i][j]表示区间[i,j]的字符串变成回文的最小花费。。。

这个可以想到。。dp[i][j] = dp[i+1][j-1] (a[i]==a[j])这个也可以想到。。。

增加和删除是等价的,所以取小的那个代价就行。。这个我也想到了。。

然后转移的地方没有特别明白。。。

和之前的找到一个划分的点k不同的是。。。

如果不等于。。

那么

1,
2dp[i][j] = min(dp[i][j],dp[i+1][j]+cost[a[i]]);
3		dp[i][j] = min(dp[i][j],dp[i][j-1]+cost[a[j]]);

这个方程可以理解。。。但是感觉自己想不出来 QAQ

以及。。我初始化写错了。。。

以为是求 最小值就初始化成了0x3f…

但是这样是错的。。。

具体见代码注释。。。

 1/* ***********************************************
 2Author :111qqz
 3Created Time :2016年07月25日 星期一 19时42分19秒
 4File Name :code/poj/3280.cpp
 5 ************************************************ */
 6#include <cstdio>
 7#include <cstring>
 8#include <iostream>
 9#include <algorithm>
10#include <vector>
11#include <queue>
12#include <set>
13#include <map>
14#include <string>
15#include <cmath>
16#include <cstdlib>
17#include <ctime>
18#define fst first
19#define sec second
20#define lson l,m,rt<<1
21#define rson m+1,r,rt<<1|1
22#define ms(a,x) memset(a,x,sizeof(a))
23typedef long long LL;
24#define pi pair < int ,int >
25#define MP make_pair
26using namespace std;
27const double eps = 1E-8;
28const int dx4[4]={1,0,0,-1};
29const int dy4[4]={0,-1,1,0};
30const int inf = 0x3f3f3f3f;
31const int N=2E3+7;
32char s[N];
33int dp[N][N];
34int n,len;
35int cost[N];
36int a[N];
37int main()
38{
39#ifndef  ONLINE_JUDGE
40    freopen("code/in.txt","r",stdin);
41#endif
42    scanf("%d%d",&n,&len);
43    scanf("%s",s);
44    for ( int i = 0 ; i < len ; i++)
45    {
46	a[i] = s[i]-'a'+1;
47    }
48    //	for ( int i = 1 ; i <= len ; i++) cout<<"a[i]:"<<a[i]<<endl;
49    getchar();
50    for ( int i = 1 ; i <= n ; i++)
51    {
52	char ch;
53	int val;
54	int x,y;
55	scanf("%c %d %d\n",&ch,&x,&y);
56	val = ch-'a'+1;
57	cost[val]=min(x,y);
58    }
59
60    ms(dp,0);
61    //也告诉了我们。。。求最大最小和初始化成0还是正无穷没有关系。。。。要仔细分析。。
62    //初始化成0可以理解成。。。初始不知道字符串。。认为是空。。。空是回文。。所以没有花费。。。
63    //	for ( int i = 0 ; i < len ; i++)
64    //	    dp[i][i] = cost[a[i]];   //错误的初始化。。。。智力-2
65    //
66    //	这个初始化是错误的。 如果目前只有一个字符a,那么使之变成回文的除了增加一个a,删除一个a,还可以再两边增加两个相同的字符来实现。
67    //	而这个初始化没有考虑第三种情况。。。好菜啊。
68
69
70
71    for ( int l = 1 ; l < len ; l++)
72	for ( int i = 0,j = l ; j <len ; i++,j++)
73	{
74	    dp[i][j] = inf;
75	    //	cout<<"dp[i][j]:"<<dp[i][j]<<endl;
76	    if (a[i]==a[j]) dp[i][j] = dp[i+1][j-1];
77	    else
78	    {
79		dp[i][j] = min(dp[i][j],dp[i+1][j]+cost[a[i]]);
80		dp[i][j] = min(dp[i][j],dp[i][j-1]+cost[a[j]]);
81	    }
82	    //	cout<<"dpi0[i][j]::::"<<dp[i][j]<<endl;
83	    //		for ( int k = i ; k < j ; k++)
84	    //		{
85	    //		    dp[i][j] = min(dp[i][j],dp[k+1][j]);
86	    //		    dp[i][j] = min(dp[i][j],dp[i][k]);
87	    //		    printf("i==%d j==%d k==%d dp[i][k]==%d dp[k+1][j]%d\n",i,j,k,dp[i][k],dp[k+1][j]);
88	    //		for ( int k = i ; k < j ; k++)
89	    //		    dp[i][j] = min(dp[i][j],dp[])
90	    //		}
91	    //		cout<<"i:"<<i<<" j:"<<j<<" dp[i][j]:"<<dp[i][j]<<endl;
92	    //	ans = min(dp[i][j],ans);
93	}
94    printf("%d\n",dp[0][len-1]);
95#ifndef ONLINE_JUDGE
96    fclose(stdin);
97#endif
98    return 0;
99}

相关文章

light oj 1422 - Halloween Costumes (区间dp)

·2 分钟
light oj 1422 题目链接 题意: 按顺序去参加舞会。每个舞会对衣服都有要求。可以连续穿好多件衣服。需要时候就脱下来,但是一旦脱下来,这件衣服就报废了。问最少需要几件衣服。

poj 2955 Brackets(区间dp....括号匹配。。。人生第一道区间dp)

·2 分钟
poj2955题目链接 题意:给出若干括号,问最大匹配数是多少。 思路:没有思路。我知道这是dp。。。然后其他就什么都不知道了。。。转移方程? 完全没思路。。知道了转移方程。。。。嗯,还是不会。。。边界怎么写?状态怎么推?循环顺序? 循环次序?我一点思路都没有。。。。。

hdu 1114 - Piggy-Bank (完全背包)

·2 分钟
F - Piggy-Bank **Time Limit:**1000MS **Memory Limit:**32768KB 64bit IO Format:%I64d & %I64u Submit Status Description Before ACM can do anything, a budget must be prepared and the necessary financial support obtained. The main income for this action comes from Irreversibly Bound Money (IBM). The idea behind is simple. Whenever some ACM member has any small money, he takes all the coins and throws them into a piggy-bank. You know that this process is irreversible, the coins cannot be removed without breaking the pig. After a sufficiently long time, there should be enough cash in the piggy-bank to pay everything that needs to be paid.

hdu 1087 - Super Jumping! Jumping! Jumping! (最长上升子序列)

·2 分钟
E - Super Jumping! Jumping! Jumping! **Time Limit:**1000MS **Memory Limit:**32768KB 64bit IO Format:%I64d & %I64u Submit Status Description Nowadays, a kind of chess game called “Super Jumping! Jumping! Jumping!” is very popular in HDU. Maybe you are a good boy, and know little about this game, so I introduce it to you now.