bzoj 1070(区间dp)

来源:互联网 发布:elsevier是什么数据库 编辑:程序博客网 时间:2024/05/21 16:58

传送门
题解:
dp[i][j]表示把[i,j]变成回文串的最小代价,显然删除一个不和谐的字符和添加一个是等价的,所以对于每个字符只取删除/添加的最小值。然后记忆化搜索即可,好像也可以直接dp。
P.S.迷之memset要RE。。。以后dp还是尽量用for初始化,免得把一些不易发现的不合法状态弄出问题。。。

#include<bits/stdc++.h>using namespace std;int dp[2002][2002],num[2002];char ss[2002],ch[2];int cost[30];int n,m,x,y;int dfs(int l,int r) {    if (l==r) return dp[l][r]=0;    if (~dp[l][r]) return dp[l][r];    int res=0x3f3f3f3f;    res=min(dfs(l,r-1)+cost[num[r]],dfs(l+1,r)+cost[num[l]]);    if (num[l]==num[r]) res=min(res,dfs(l+1,r-1));    return dp[l][r]=res;}int main() {//  freopen("bzoj 1710.in","r",stdin);    scanf("%d%d%s",&m,&n,ss+1);    for (int i=1;i<=n;++i) num[i]=ss[i]-'a'+1;    for (int i=1;i<=m;++i) {        scanf("%s%d%d",ch,&x,&y);        cost[ch[0]-'a'+1]=min(x,y);    }//  memset(dp,-1,sizeof(dp));    for (int i=1;i<=n;++i)        for (int j=i;j<=n;++j)         dp[i][j]=-1;    printf("%d\n",dfs(1,n));    return 0;}
原创粉丝点击