zoukankan      html  css  js  c++  java
  • AtCoder AGC022E Median Replace (字符串、自动机、贪心、计数)

    题目链接

    https://atcoder.jp/contests/agc022/tasks/agc022_e

    题解

    感觉官方题解很神仙,听完另一种做法之后发现是自己太智障了
    考虑一个串怎么样可以缩成 (1), 可以采取如下贪心策略:从前往后扫描整个串,同时维护一个栈。每次把新元素压入栈顶,如果栈顶出现了 000 则消去两个 0,如果出现了 01 则直接消去。最后得到的串含有不超过 (2)0,且一定是前若干字符为 1 后若干个字符为 0. 不难发现原串可以缩成 1 当且仅当最后的串中 1 的个数大于 0 的个数。
    因此,若 1 的个数超过 (2),那么一定可以缩成 1,我们可以认为 1 的个数就是 (2).
    那么我们可以得到一个状态数为 (9) 的自动机(01 均为 (0) 个、(1) 个或 (2) 个),在上面跑 DP 即可。
    时间复杂度 (O(n)).

    代码

    #include<bits/stdc++.h>
    #define llong long long
    #define mkpr make_pair
    #define riterator reverse_iterator
    using namespace std;
    
    inline int read()
    {
    	int x = 0,f = 1; char ch = getchar();
    	for(;!isdigit(ch);ch=getchar()) {if(ch=='-') f = -1;}
    	for(; isdigit(ch);ch=getchar()) {x = x*10+ch-48;}
    	return x*f;
    }
    
    const int N = 3e5;
    const int P = 1e9+7;
    char a[N+3];
    int trans[9][2] = {{3,1},{4,2},{5,2},{6,0},{7,1},{8,2},{3,3},{4,4},{5,5}};
    llong dp[N+3][9];
    int n;
    
    void updsum(llong &x,llong y) {x = x+y>=P?x+y-P:x+y;}
    
    int main()
    {
    	scanf("%s",a+1); n = strlen(a+1);
    	dp[0][0] = 1ll;
    	for(int i=1; i<=n; i++)
    	{
    		for(int j=0; j<9; j++)
    		{
    			if(a[i]!='1') {updsum(dp[i][trans[j][0]],dp[i-1][j]);}
    			if(a[i]!='0') {updsum(dp[i][trans[j][1]],dp[i-1][j]);}
    		}
    	}
    	llong ans = (dp[n][1]+dp[n][2]+dp[n][5]+dp[n][8])%P;
    	printf("%lld
    ",ans);
    	return 0;
    }
    
  • 相关阅读:
    MQTT TLS 加密传输
    python多进程并发redis
    各种消息队列的特点
    mqtt异步publish方法
    Numpy API Analysis
    Karma install steps for unit test of Angular JS app
    reinstall bower command
    Simulate getter in JavaScript by valueOf and toString method
    How to: Raise and Consume Events
    获取对象的类型信息 (JavaScript)
  • 原文地址:https://www.cnblogs.com/suncongbo/p/12553729.html
Copyright © 2011-2022 走看看