UVA1625 Color Length(线性DP

UVA1625 Color Length (线性DP)

类似于LCS问题,可以用dp[i][j]来表示已选择序列1前i项和序列2前j项的最小目标函数值L( c )。显然,dp[0][0]=0;

因为在选序列1第i个项的前提是前i-1个项必须被选择,序列2同理。
所以dp[i][j]仅可能从dp[i-1][j]和dp[i][j-1]两种状态转移而来。

对目标函数的处理,借鉴紫书上的方法:当把一个元素放到最终序列的时候,递增“已经出现但还未结束”的颜色的L( c )值。

最初的想法是在每次状态转移的时候计算目标函数增加值,对26个字母逐一判断是否出现在最终序列且还未选择完,结果TLE。

参考了他人的想法,先预处理好已选了序列1前i个,序列2前j个时,需要进行递增的数目,用cnt[i][j]表示。

显然,当i!=0且j!=0是,cnt[i][j]可以由cnt[i-1][j]或者cnt[i][j-1]得到。
例如,从cnt[i-1][j]递推,对序列1的第i项进行判断.

如果它是第一次出现在最终序列内且后续还会出现,则cnt[i][j]=cnt[i-1][j]+1;

如果它是最后一次出现在最终序列里,则cnt[i][j]=cnt[i-1][j]-1;这样的判别方法,同时也考虑到只出现一次的颜色。

显然,当i=0时,cnt[i][j]只能从cnt[i][j-1]得来;当j=0时,cnt[i][j]只能从cnt[i-1][j]得来。

我们可以将元素的start值初始化为INF,把元素的end值初始化为-1或0,简化判断过程。

所以,通过上述讨论,可得状态转移方程
1、dp[i][j]=dp[i-1][j]+cnt[i-1][j] (j=0)
2、dp[i][j]=dp[i][j-1]+cnt[i][j-1] (i=0)
3、dp[i][j]=min(dp[i-1][j]+cnt[i-1][j],dp[i][j-1]+cnt[i][j-1] ) (i!=0且j!=0)

预处理的时间复杂度O(nm),dp的时间复杂度O(nm)

#include<bits/stdc++.h>
using namespace std;
const int max_n=5e3+5;
const int INF=0x3f3f3f3f;
string s1,s2;
int n,m;
int dp[max_n][max_n];
int cnt[max_n][max_n];
int start_1[26];
int end_1[26];
int start_2[26];
int end_2[26];
void solve(void)
{
   
	memset(start_1,0x3f,sizeof(start_1));
	memset(start_2,0x3f
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值