zoukankan      html  css  js  c++  java
  • [Luogu] CF1443B Saving the City

    (Link)

    Description

    你有一段(01)串,你可以选择花费(B)的代价将一个(0)变为(1),也可以花费(A)的代价将一段连续的(1)变为(0),问你最少需要多少代价,才能把整个串都变为(0)

    Solution

    这道题其实不太像(DP)

    会发现无论对当前点做什么操作,都不会会后面点的选择有影响,即无后效性。

    所以对于一段连续的(1),我们在最后一个点考虑把它全部消掉的代价。可以用(A)直接消掉,也可以把它和下一段连续的(1)一起消掉,这时花费为把它们中间的(0)都推平的代价(即(len imes{B}))。

    这样考虑一定是对的。因为对于下一段连续的(1),用(A)的代价直接消掉,如果之前把它和上一段的(0)都推平了,就等于把它们一起消掉,否则就只是花费(A)把这一段消掉。

    要注意判断这一段(1)后面没有(1)的情况。

    Code

    #include <bits/stdc++.h>
    
    using namespace std;
    
    int t, a, b;
    
    char ch[100005];
    
    int read()
    {
    	int x = 0, fl = 1; char ch = getchar();
    	while (ch < '0' || ch > '9') { if (ch == '-') fl = -1; ch = getchar();}
    	while (ch >= '0' && ch <= '9') {x = (x << 1) + (x << 3) + ch - '0'; ch = getchar();}
    	return x * fl;
    }
    
    int main()
    {
    	t = read();
    	while (t -- )
    	{
    		a = read(); b = read();
    		scanf("%s", ch + 1);
    		int l = strlen(ch + 1), res = 0;
    		for (int i = 1; i <= l; i ++ )
    		{
    			if ((ch[i] == '1' && ch[i + 1] == '0') || (i == l && ch[i] == '1'))
    			{
    				int pos = l + 1;
    				for (int j = i + 1; j <= l; j ++ )
    				{
    					if (ch[j] == '1')
    					{
    						pos = j;
    						break;
    					}
    				}
    				if (pos == l + 1) res += a;
    				else res += min(a, (pos - i - 1) * b);
    				i = pos - 1;
    			}
    		}
    		printf("%d
    ", res);
    	}
    	return 0;
    }
    
  • 相关阅读:
    0052 html5多媒体音频标签audio
    0051 HTML5概述、新增标签、简单案例
    0050 VSCode软件
    0048 :focus -- 获得焦点元素
    0046 CSS3过渡:transition
    Linux 中的常见锁及其基本原理
    小程序海报最佳实现思路,可视化编辑直接生成代码使用
    babel插件的相关知识
    vue-next 函数式 api
    小程序如何改变onLoad 的执行时机?
  • 原文地址:https://www.cnblogs.com/andysj/p/14015693.html
Copyright © 2011-2022 走看看