zoukankan      html  css  js  c++  java
  • POJ

    题目大意:

    现在有一串字符(不一定是回文串),每个字母都有添加和删去的花费,问将这一串字符变成回文串的最小花费是
    多少
    

    分析:

    方法一:区间dp
    实际上删去和添加一个字母是等价的,因为添加和删去都是为了让这一段变成回文的,这对于我们dp[i][j]([i,j]
    这一段变成回文所需要花的花费)来讲,我们只要取删除和添加中的最小花费就行了。而状态转移方程也是比较好
    推的:
    s[i]==s[j]则说明dp[i][j]=dp[i+1][j-1],否则
    dp[i][j]=min(dp[i+1][j]+cnt[s[i]-'a'],dp[i][j-1]+cnt[s[j]-'a'])
    最后的dp[0][m-1]就是我们需要的答案
    方法二:dfs,看代码
    

    code1(区间dp):

    #define debug
    #include<stdio.h>
    #include<math.h>
    #include<cmath>
    #include<queue>
    #include<stack>
    #include<string>
    #include<cstring>
    #include<string.h>
    #include<algorithm>
    #include<iostream>
    #include<vector>
    #include<functional>
    #include<iomanip>
    #include<map>
    #include<set>
    #define pb push_back
    #define dbg(x) cout<<#x<<" = "<<(x)<<endl;
    #define lson l,m,rt<<1
    #define cmm(x) cout<<"("<<(x)<<")";
    #define rson m+1,r,rt<<1|1
    using namespace std;
    typedef long long ll;
    const int maxn=1e5;
    const int INF=0x3f3f3f3f;
    const ll inf=0x7fffff;
    const int mod=1e9+7;
    const int MOD=10007;
    //----
    //define
    int dp[2005][2005];
    int cnt[26];
    char s[maxn];
    //solve
    void solve() {
    	int n,m,dec,adc;
    	char tmp;
    	scanf("%d%d",&n,&m);
    	getchar();
    	scanf("%s",s);
    	getchar();
    	for(int i=0; i<n; i++) {
    		scanf("%c%d%d",&tmp,&dec,&adc);
    		getchar();
    		cnt[tmp-'a']=min(dec,adc);
    	}
    	for(int i=1; i<m; i++) {
    		dp[i][i]=0;//单个字符就是一个回文,所以赋值为0 
    		for(int j=0; j+i<m; j++) {
    			if(s[j]==s[j+i])dp[j][j+i]=dp[j+1][j+i-1];
    			else
    				dp[j][j+i]=min(dp[j+1][j+i]+cnt[s[j]-'a'],dp[j][j+i-1]+cnt[s[j+i]-'a']);
    		}
    	}
    	printf("%d",dp[0][m-1]);
    }
    
    int main() {
    //	ios_base::sync_with_stdio(0);
    #ifdef debug
    	freopen("in.txt","r",stdin);
    //	freopen("out.txt","w",stdout);
    #endif
    //	cin.tie(0);
    //	cout.tie(0);
    	solve();
    	return 0;
    }
    

     code2(dfs):

    #define debug
    #include<stdio.h>
    #include<math.h>
    #include<cmath>
    #include<queue>
    #include<stack>
    #include<string>
    #include<cstring>
    #include<string.h>
    #include<algorithm>
    #include<iostream>
    #include<vector>
    #include<functional>
    #include<iomanip>
    #include<map>
    #include<set>
    #define pb push_back
    #define dbg(x) cout<<#x<<" = "<<(x)<<endl;
    #define lson l,m,rt<<1
    #define cmm(x) cout<<"("<<(x)<<")";
    #define rson m+1,r,rt<<1|1
    using namespace std;
    typedef long long ll;
    const int maxn=1e5;
    const ll INF=0x3f3f3f3f;
    const ll inf=0x7fffff;
    const int mod=1e9+7;
    const int MOD=10007;
    //----
    //define
    int dp[2005][2005];
    int cnt[26];
    char s[maxn];
    //dfs
    int dfs(int l,int r){
    	if(l>=r)return dp[l][r]=0;
    	if(dp[l][r]!=-1)return dp[l][r];
    	if(s[l]!=s[r]){
    		return dp[l][r]=min(dfs(l+1,r)+cnt[s[l]-'a'],dfs(l,r-1)+cnt[s[r]-'a']);
    	}
    	return dp[l][r]=dfs(l+1,r-1);
    } 
    //solve
    void solve() {
    	int n,m,dec,adc;
    	char tmp;
    	scanf("%d%d",&n,&m);
    	getchar();
    	scanf("%s",s);
    	getchar();
    	memset(dp,-1,sizeof(dp));
    	for(int i=0;i<n;i++){
    		scanf("%c%d%d",&tmp,&dec,&adc);
    		getchar();
    		cnt[tmp-'a']=min(dec,adc);
    	}
    	printf("%d",dfs(0,m-1));
    }
    
    int main() {
    //	ios_base::sync_with_stdio(0);
    #ifdef debug
    	freopen("in.txt","r",stdin);
    //	freopen("out.txt","w",stdout);
    #endif
    //	cin.tie(0);
    //	cout.tie(0);
    	solve();
    	return 0;
    }
    
  • 相关阅读:
    集合-ConcurrentSkipListMap 源码解析
    集合-跳表SkipList
    集合-ConcurrentHashMap 源码解析
    >>《移动设计模式大观.pdf》
    >>《《iOS 人机界面准则》中文版.pdf》
    >《Web导航设计.pdf》
    >>《设计心理学名着-2 情感化设计 诺曼着.pdf》
    自制网页(html+css+js+jQuery)
    仿写抽屉新热榜 (html+css)
    运动员喝饮料问题
  • 原文地址:https://www.cnblogs.com/visualVK/p/9151406.html
Copyright © 2011-2022 走看看