zoukankan      html  css  js  c++  java
  • Codeforces Round #604 (Div. 2) D、E、F题解

    Beautiful Sequence

    [Time Limit: 1000 msquad Memory Limit: 256 MB ]

    首先我们可以考虑到 (0) 只能 和 (1) 放在一起、(3) 只能和 (2) 放在一起,那么我们想办法先把 (0)(3) 凑出来,最后就剩下 (1)(2) 了,我们只要把他们放在一起就可以了。

    所以我们可以贪心考虑三个 (string),分别长成 (0101...0101)(2323...2323)(1212...1212) 这样的,那么现在的问题就是把这三个 (string) 合并起来,那么完全可以把他们全排列并二进制枚举每个 (string) 是否翻转,然后 (check) 一遍。

    view
    #include <map>
    #include <set>
    #include <list>
    #include <ctime>
    #include <cmath>
    #include <stack>
    #include <queue>
    #include <cfloat>
    #include <string>
    #include <vector>
    #include <cstdio>
    #include <bitset>
    #include <cstdlib>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #define  lowbit(x)  x & (-x)
    #define  mes(a, b)  memset(a, b, sizeof a)
    #define  fi         first
    #define  se         second
    #define  pb         push_back
    #define  pii        pair<int, int>
    #define  INOPEN     freopen("in.txt", "r", stdin)
    #define  OUTOPEN    freopen("out.txt", "w", stdout)
    
    typedef unsigned long long int ull;
    typedef long long int ll;
    const int    maxn = 2e5 + 10;
    const int    maxm = 1e5 + 10;
    const ll     mod  = 1e9 + 7;
    const ll     INF  = 1e18 + 100;
    const int    inf  = 0x3f3f3f3f;
    const double pi   = acos(-1.0);
    const double eps  = 1e-8;
    using namespace std;
    
    int n, m;
    int cas, tol, T;
    int a, b, c, d;
    
    string s[4], ss;
    
    bool ok(string a, string b, string c) {
    	int lena = a.size(), lenb = b.size(), lenc = c.size();
    	int len = lena+lenb+lenc;
    	for(int i=0; i<7; i++) {
    		if(i&(1<<(0))) {
    			reverse(a.begin(), a.end());
    		}
    		if(i&(1<<(1))) {
    			reverse(b.begin(), b.end());
    		}
    		if(i&(1<<(2))) {
    			reverse(c.begin(), c.end());
    		}
    		ss = a+b+c;
    		if(i&(1<<(0))) {
    			reverse(a.begin(), a.end());
    		}
    		if(i&(1<<(1))) {
    			reverse(b.begin(), b.end());
    		}
    		if(i&(1<<(2))) {
    			reverse(c.begin(), c.end());
    		}
    
    		int flag = 1;
    		for(int i=1; i<len; i++) {
    			if(abs(ss[i]-ss[i-1])!=1) {
    				flag = 0;
    				break;
    			}
    		}
    		if(flag) {
    			printf("YES
    ");
    			for(int i=0; i<len; i++) {
    				printf("%c%c", ss[i], i==len-1 ? '
    ':' ');
    			}
    			return true;
    		}
    	}
    	return false;
    }
    
    int main() {
    	scanf("%d%d%d%d", &a, &b, &c, &d);
    	s[1] = "";
    	while(a&&b) {
    		s[1] += "01";
    		a--, b--;
    	}
    	if(a) {
    		s[1] += "0";
    		a--;
    	}
    	if(b) {
    		s[1] = "1"+s[1];
    		b--;
    	}
    
    	s[3] = "";
    	while(c&&d) {
    		s[3] += "23";
    		c--, d--;
    	}
    	if(c) {
    		s[3] += "2";
    		c--;
    	}
    	if(d) {
    		s[3] = "3"+s[3];
    		d--;
    	}
    	
    	s[2] = "";
    	while(b&&c) {
    		s[2] += "12";
    		b--, c--;
    	}
    	if(b) {
    		s[2] += "1";
    		b--;
    	}
    	if(c) {
    		s[2] = "2"+s[2];
    		c--;
    	}
    	if(a||b||c||d)	return 0*puts("NO");
    	do {
    		if(ok(s[1], s[2], s[3]))
    			return 0;
    	} while(next_permutation(s+1, s+1+3));
    	puts("NO");
    	return 0;
    }
    

    Beautiful Mirrors

    [Time Limit: 2000 msquad Memory Limit: 256 MB ]

    首先令 (dp[i]) 表示从第 (i) 天到结束所需要的期望天数,为了方便,可以假设 (n+1) 天为结束位置,那么 (dp[n+1] = 0)

    对于 (1<=i<=n),有 (dp[i] = frac{p_i*dp[i+1] + (100-p_i)*dp[1]}{100}+1)

    然后一直带进去,最后可以发现 (dp[1]) 可以表示为

    [ dp[1] = A*dp[1] + B + 1 ]

    其中 (A、B) 都是具体的数字,那么就得到的 (dp[1]) 的值。

    view
    #include <map>
    #include <set>
    #include <list>
    #include <ctime>
    #include <cmath>
    #include <stack>
    #include <queue>
    #include <cfloat>
    #include <string>
    #include <vector>
    #include <cstdio>
    #include <bitset>
    #include <cstdlib>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #define  lowbit(x)  x & (-x)
    #define  mes(a, b)  memset(a, b, sizeof a)
    #define  fi         first
    #define  se         second
    #define  pb         push_back
    #define  pii        pair<int, int>
    #define  INOPEN     freopen("in.txt", "r", stdin)
    #define  OUTOPEN    freopen("out.txt", "w", stdout)
     
    typedef unsigned long long int ull;
    typedef long long int ll;
    const int    maxn = 2e5 + 10;
    const int    maxm = 1e5 + 10;
    const ll     mod  = 998244353;
    const ll     INF  = 1e18 + 100;
    const int    inf  = 0x3f3f3f3f;
    const double pi   = acos(-1.0);
    const double eps  = 1e-8;
    using namespace std;
     
    int n, m;
    int cas, tol, T;
     
    int p[maxn];
     
    ll fpow(ll a, ll b) {
    	ll ans = 1;
    	while(b) {
    		if(b&1)	ans = ans*a%mod;
    		 a = a*a%mod;
    		 b >>= 1;
    	}
    	return ans;
    }
     
    int main() {
    	ll M = fpow(100ll, mod-2);
    	scanf("%d", &n);
    	for(int i=1; i<=n; i++) {
    		scanf("%d", &p[i]);
    	}
    	ll b = 0, c = 0;
    	ll tmpb = 1;
    	for(int i=1; i<=n; i++) {
    		b += tmpb*(100ll-p[i])%mod*M%mod;
    		c += tmpb;
    		tmpb *= p[i]*M%mod;
    		b %= mod, c %=mod, tmpb %= mod;
    	}
    	b = mod-b+1;
    	b = (b%mod+mod)%mod;
    	ll ans = c*fpow(b, mod-2)%mod;
    	printf("%lld
    ", ans);
    	return 0;
    }
    

    Beautiful Bracket Sequence (easy version)

    [Time Limit: 2000 msquad Memory Limit: 256 MB ]

    (dp[i][j]) 表示从 (i)(j) 区间内,所有情况的括号最深深度之和。

    转移的时候令 (dp[i][i] = 0)(dp[i][i+1])(s[i])(s[i+1]) 能否组成 (())

    对于更大的区间,只需要考虑最左和最右端点就可以。

    1. 如果(s[i]) 可以放成 (()

      • 如果 (s[j]) 可以放成 (()(dp[i][j] += dp[i][j-1])
      • 如果 (s[j]) 可以放成 ())(dp[i][j] += dp[i+1][j-1] + 2^k)(k) 代表 ([i+1,j-1]) 这段内 (?) 的个数。
    2. 如果 (s[i]) 可以放成 ())

      • 如果 (s[j]) 可以放成 (()(dp[i][j] += dp[i+1][j-1])
      • 如果 (s[j]) 可以放成 ())(dp[i][j] += dp[i+1][j])

    然后有一部分会被重复计算,也就是 (dp[i+1][j-1]) 这一段,所以只要顺便记录一下转移过程中计算了几次这一段,然后扣掉多计算的就可以了。

    view
    #include <map>
    #include <set>
    #include <list>
    #include <ctime>
    #include <cmath>
    #include <stack>
    #include <queue>
    #include <cfloat>
    #include <string>
    #include <vector>
    #include <cstdio>
    #include <bitset>
    #include <cstdlib>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #define  lowbit(x)  x & (-x)
    #define  mes(a, b)  memset(a, b, sizeof a)
    #define  fi         first
    #define  se         second
    #define  pb         push_back
    #define  pii        pair<int, int>
    #define  INOPEN     freopen("in.txt", "r", stdin)
    #define  OUTOPEN    freopen("out.txt", "w", stdout)
     
    typedef unsigned long long int ull;
    typedef long long int ll;
    const int    maxn = 2e3 + 10;
    const int    maxm = 1e5 + 10;
    const ll     mod  = 998244353;
    const ll     INF  = 1e18 + 100;
    const int    inf  = 0x3f3f3f3f;
    const double pi   = acos(-1.0);
    const double eps  = 1e-8;
    using namespace std;
     
    int n, m, TT;
    int cas, tol;
     
    int a[maxn] = {0};
    char s[maxn];
    ll dp[maxn][maxn];
     
    ll fpow(ll a, ll b) {
    	ll ans = 1;
      	while(b) {
    		if(b&1)	ans = ans*a%mod;
    		a = a*a%mod;
    		b >>= 1;
    	}
    	return ans;
    }
     
    int main() {
    	scanf("%s", s+1);
    	n = strlen(s+1);
    	for(int i=1; i<=n; i++) {
    		a[i] = a[i-1]+(s[i]=='?');
    		dp[i][i] = 0;
    		dp[i][i+1] = (i+1<=n && s[i]!=')' && s[i+1]!='(');
    	}
    	for(int d=3; d<=n; d++) {
    		for(int i=1, j=d, c; j<=n; i++, j++) {
    			dp[i][j] = 0, c = -1;
    			if(s[i] != ')') {
    				if(s[j] != ')')	dp[i][j] += dp[i][j-1], c++;
    				if(s[j] != '(')	dp[i][j] += dp[i+1][j-1] + fpow(2, a[j-1]-a[i]);
    			}
    			if(s[i] != '(') {
    				if(s[j] != ')')	dp[i][j] += dp[i+1][j-1], c++;
    				if(s[j] != '(')	dp[i][j] += dp[i+1][j], c++;
    			}
    			dp[i][j] -= max(c, 0)*dp[i+1][j-1];
    			dp[i][j] %= mod;
    //			printf("dp[%d][%d] = %lld
    ", i, j, dp[i][j]);
    		}
    	}
    	printf("%lld
    ", dp[1][n]);
        return 0;
    }
    
  • 相关阅读:
    PsySH——PHP交互式控制台
    CentOS 6.5升级Python和安装IPython
    yii2 邮件发送
    Centos 6.5安装最新版谷歌浏览器-Chrome
    centos 6.5 设置屏幕保护
    PHP实现生成唯一编号(36进制的不重复编号)
    十位用户唯一ID生成策略
    0基础学java_for循环
    0基础学java_while循环
    0基础学java_逻辑变量 逻辑表达式 和条件句
  • 原文地址:https://www.cnblogs.com/Jiaaaaaaaqi/p/12037553.html
Copyright © 2011-2022 走看看