poj 3280(区间dp、java实现)

代码注释清晰,如果还不能理解请参考我的另一篇博客,链接: (详解)区间DP —— 平行四边形优化.,希望对你有所帮助!!!
题目信息:

描述

跟踪所有母牛可能是一项艰巨的任务,因此,农夫约翰(Farmer John)已安装了一个使它自动化的系统。他在每头奶牛上安装了一个电子ID标签,当奶牛经过扫描仪时,系统会读取该电子ID标签。各ID标签的内容目前单个字符串与长度中号(1≤ 中号 ≤2000)从的字母表字符绘制Ñ(1≤ Ñ ≤26)不同的符号(即,小写罗马字母)。

母牛是顽皮的动物,有时试图通过向后走来欺骗该系统。尽管ID为“ abcba”的母牛无论走到哪个方向都将读取相同的信息,但是ID为“ abcb”的母牛可能会注册为两个不同的ID(“ abcb”和“ bcba”)。

FJ希望更改奶牛的ID标签,以便无论奶牛走过的方向如何都可以读取相同的信息。例如,可以通过在末尾添加“ a”以形成“ abcba”来更改“ abcb”,以便ID是回文的(向前和向后读取相同的内容)。将ID更改为回文的其他一些方法包括在开头添加三个字母“ bcb”以产生ID“ bcbabcb”,或删除字母“ a”以产生ID“ bcb”。可以在字符串的任何位置添加或删除字符,从而产生比原始字符串长或短的字符串。

不幸的是,由于ID标签是电子标签,因此每个字符的插入或删除都有一个成本(0≤ 成本 ≤10,000),具体取决于要添加或删除哪个字符值。考虑到母牛ID标签的内容以及插入或删除每个字母字符的成本,请找到更改ID标签以使其满足FJ要求的最低成本。空的ID标签被认为满足向前和向后读取相同ID的要求。只能将带有相关费用的字母添加到字符串中。

输入项

第1行:两个以空格分隔的整数:N和M
第2行:此行恰好包含构成初始ID字符串的M个字符
第3行。N +2:每行包含三个以空格分隔的实体:输入字母的字符和两个整数,分别是添加和删除该字符的成本。

输出
第1行:具有单个整数的一行,这是更改给定名称标签的最低成本。

样本输入
3 4
abcb
a 1000 1100
b 350 700
c200 800

样本输出
900

注意事项:

  • 区间DP模版(三要素):
    区间长度
    区间起点、终点(由长度与起点推出终点、最后一个起点的位置)

AC代码(java):

import java.util.*;

public class Main {
	public static void main(String[] args) {
		Scanner sc=new Scanner(System.in);
		int n=sc.nextInt();
		int m=sc.nextInt();
		String str=sc.nextLine();	//吸收空格
		char[] s=sc.nextLine().toCharArray();	//记录字符串
		int[][] dp=new int[m+5][m+5];	//状态数组:保存子字符串s(i,j)转化为回文序列的最小花费
		int[] cost=new int[30];	//记录某个字母最小花费
		for(int i=1;i<=n;i++) {
			char c=sc.next().charAt(0);
			int x=sc.nextInt();
			int y=sc.nextInt();
			cost[c-'a']=Math.min(x, y);	//记录最小花费(删除还是添加)
		}
		
		for(int len=2;len<=m;len++) {	//枚举长度
			for(int i=m-len;i>=0;i--) {
				int j=i+len-1;	//通过起点计算终点
				if(s[i]==s[j]) {	//第一种情况
					dp[i][j]=dp[i+1][j-1];
				}
				else {
					dp[i][j]=Math.min(dp[i+1][j]+cost[s[i]-'a'], dp[i][j-1]+cost[s[j]-'a']);	//第二种情况,状态转移方程
				}
			}
		}
		
		System.out.println(dp[0][m-1]);
				
	}
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值