首页 > 其他分享 >AT_abc303_d

AT_abc303_d

时间:2024-01-20 18:26:14浏览次数:29  
标签:min int abc303 else include dp

看到本题,很容易想到贪心,对每一段相同的子串计算最小代价。但这种思路的评测结果显示有 \(3\) 个测试点 WA 了,因此解法错误。既然贪心行不通,我们不妨使用 dp,对每一位进行分类讨论并求最小耗时。

设 \(dp_{i,j}\) 表示 Capslock 状态为 \(j\) 时(\(j\) 为 \(0\) 或\(1\),\(0\) 表示熄灯,\(1\) 表示亮灯),前 \(i\) 位的最小耗时,接下来具体分析状态转移方程:

记 \(s_i\) 表示 \(s\) 中下标为 \(i\) 的字符。

  • \(s_i = s_{i - 1}\)

这种情况下有如下状态转移方程:

  1. 若 \(s_i\) 为 A,则有

\[dp_{i,0} = \min( dp_{i-1,0} + y ,dp_{i-1,1} + z + y ) \]

\[dp_{i,1} = \min( dp_{i-1,0} + z + x,dp_{i-1,1} + x ) \]

  1. 若 \(s_i\) 为 a,则有

\[dp_{i,0} = \min( dp_{i-1,0} + x ,dp_{i-1,1} + z + x ) \]

\[dp_{i,1} = \min( dp_{i-1,0} + z + y,dp_{i-1,1} + y ) \]

  • \(s_i \ne s_{i - 1}\)

推导过程同理,这里略过。

总结

这些式子看起来很长,其实理解起来并不难:先看状态是否一致,不一致则加上 \(z\),然后再看只按 a 是否为需要的字母,如果不是则加上 \(y\),否则加上 \(x\)。

具体实现如下:

#include <iostream>
#include <cstdio>
#include <cstring>
#define int long long

using namespace std;

int x,y,z,len,l,nw;
int ans;
int dp[1000001][2];
char s[1000001];

signed main()
{
	cin >> x >> y >> z;
	cin >> s;
	len = 1;
	if( s[0] == 'a' )
	{
		dp[0][0] = x;
		dp[0][1] = z + y;
	}
	else
	{
		dp[0][0] = y;
		dp[0][1] = z + x;
	}
	l = strlen(s);
	for( int i = 1 ; i < l ; i ++ )
	{
		if( s[i] == s[i - 1] )
		{
			if( s[i] == 'A' )
			{
				dp[i][0] = min( dp[i - 1][0] + y , dp[i - 1][1] + z + y );
				dp[i][1] = min( dp[i - 1][0] + z + x , dp[i - 1][1] + x );
			}
			else
			{
				dp[i][0] = min( dp[i - 1][0] + x , dp[i - 1][1] + z + x );
				dp[i][1] = min( dp[i - 1][0] + z + y , dp[i - 1][1] + y );
			}
		}
		else
		{
			if( s[i - 1] == 'A' )
			{
				dp[i][0] = min( dp[i - 1][0] + x , dp[i - 1][1] + x + z );
				dp[i][1] = min( dp[i - 1][0] + z + y , dp[i - 1][1] + y );
			}
			else
			{
				dp[i][0] = min( dp[i - 1][0] + y , dp[i - 1][1] + z + y );
				dp[i][1] = min( dp[i - 1][0] + z + x , dp[i - 1][1] + x );
			}
		}
	}
	cout << min( dp[l - 1][0] , dp[l - 1][1] );
	return 0;
}

标签:min,int,abc303,else,include,dp
From: https://www.cnblogs.com/-lilong-/p/17976907

相关文章

  • [ABC303G] Bags Game 解题分析
    1题目大意1.1题目翻译有两个人轮流取物品。总共有\(n\)个物品,第\(i\)个物品的价值为\(w_i\)。他们按照下面的其中一种方式取物品:取出这一排物品最前面的或者最后面的。这一步没有代价。设还剩下\(m\)个物品,那么重复取出\(\min(B,m)\)个物品,每次取出最前面的......
  • [ABC303E]
    [ABC303E]AGiftFromtheStars每次合并都是合并入度为\(1\)的点,所以合并的一定不是中心,且被合并后入度是\(2\)。因此如果某个节点的入度\(\ge3\),那么这个节点一定是中心。对于剩余的点,因为保证有解,直接当作大小为\(2\)的星处理。(注意大小为\(2\)的星共\(3\)个点)。......