Online Judge | Problem Set | Authors | Online Contests | User | ||||||
---|---|---|---|---|---|---|---|---|---|---|
Web Board Home Page F.A.Qs Statistical Charts | Current Contest Past Contests Scheduled Contests Award Contest |
贴一波思路稍微有点不一样的代码(大佬勿喷)#include <iostream> #include <cstring> #define N 2050 using namespace std; int dp[N]; char s1[N],s2[N]; int main() { int m,n,sum=0,len,cur,cur2,i,j; int c1,c2,cost[30]; char temp; scanf("%d %d",&n,&m); scanf("%s",s1); len=strlen(s1); for(i=1; i<=n; i++) { scanf(" %c %d %d",&temp,&c1,&c2); cost[temp-'a'+1]=min(c1,c2); } for(i=0; i<len; i++) { sum+=cost[s1[i]-'a'+1]; s2[len-1-i]=s1[i]; } memset(dp,0,sizeof(dp)); for(i=1; i<=len; i++) { for(j=0; j<=len; j++) { if(j==0) { cur=dp[j]; } else { cur2=dp[j]; if(s1[i-1]==s2[j-1]) { dp[j]=cur+cost[s1[i-1]-'a'+1]; } else { dp[j]=max(dp[j],dp[j-1]); } cur=cur2; } } } printf("%d\n",sum-dp[len]); return 0; } //本题的关键有两点 //一是要知道添加和删除本质效果相同,两个代价只需要取最小 //二是理解导致代价不同的本质,事实上是有一些数已经构成了回文数结构 //而不同的构造方法是利用了不同的已有回文数序列 //所以其实,要做的就是把已有的代价最大的回文序列找出来,这样就可以保证剩下字符的处理代价最小 //要找已有的代价最大的回文序列,在一个字符串内很难找到,难以记录与计算 //所以考虑转化,转化为两个字符串的最大代价公共子序列问题,另一个字符串是原字符串的倒序 //而这个问题是最长公共子序列问题的变式,用dp可解,只需要变一下递推式即可 //小套路:对于字符串题目而言,很多时候都是利用区间端点定义dp Followed by: Post your reply here: |
All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator