↓ 跳过正文
  1. Posts/

poj 3280 Cheapest Palindrome (区间dp)

·866 字·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)

·669 字·2 分钟
light oj 1422 题目链接 题意: 按顺序去参加舞会。每个舞会对衣服都有要求。可以连续穿好多件衣服。需要时候就脱下来,但是一旦脱下来,这件衣服就报废了。问最少需要几件衣服。 思路:没有思路。我连这题是dp都看不出来。。知道是dp也一点思路都没。。虽然这道题是道区间dp的入门题。。。但是不怕被鄙视。。我一点也没思路。。

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

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

hdu 1160 FatMouse's Speed (最长上升子序列)

·769 字·2 分钟
FatMouse’s Speed # Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 10172 Accepted Submission(s): 4521 Special Judge Problem Description FatMouse believes that the fatter a mouse is, the faster it runs. To disprove this, you want to take the data on a collection of mice and put as large a subset of this data as possible into a sequence so that the weights are increasing, but the speeds are decreasing.

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

·774 字·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! (最长上升子序列)

·536 字·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. The game can be played by two or more than two players. It consists of a chessboard(棋盘)and some chessmen(棋子), and all chessmen are marked by a positive integer or “start” or “end”. The player starts from start-point and must jumps into end-point finally. In the course of jumping, the player will visit the chessmen in the path, but everyone must jumps from one chessman to another absolutely bigger (you can assume start-point is a minimum and end-point is a maximum.). And all players cannot go backwards. One jumping can go from a chessman to next, also can go across many chessmen, and even you can straightly get to end-point from start-point. Of course you get zero point in this situation. A player is a winner if and only if he can get a bigger score according to his jumping solution. Note that your score comes from the sum of value on the chessmen in you jumping path. Your task is to output the maximum value according to the given chessmen list.