• 「BalkanOI 2018 Day2」Parentrises


    「BalkanOI 2018 Day2」Parentrises

    part1

    显然可以直接贪心。

    右括号记-1,左括号记1。

    默认起始全部绿色,不染色。

    策略如下:

    1. 从左往右扫,如果右括号个数大于左括号,那么去除目前未被染色的且在最前面的两个右括号(染成红,蓝色)。(如果没有无解)。

    2. 若此时恰好匹配,有解。

    3. 若此时左括号多出(sum)个,记录上一个括号完全匹配的地方,显然该位置往后是没有点被染色的。从右往左扫到该点,染色(2*sum)个点,如果到达某个点时候,左括号在染色后仍旧多于右括号,那么无解。

    4. 染完色输出即可。

    part2

    推论:一个括号串能够满足条件当且仅当所有前缀中右括号数量小于等于左括号×2,所有后缀中,左括号个数小于等于右括号数×2。

    一段括号串的值为括号的和。

    可以记录左括号×2-右括号数(j),而 后缀中右括号×2-左括号的最小值 = (min(总括号值- 某前缀中左括号×2-右括号)),相当于记录前缀中(j)的最大值(k)

    那么可以定义出(dp)状态(dp[i][j][k]),表示当前已经有(i)个括号,(j,k)如上。

    之后转移时保证(j geq 0),对于一个状态,如果它后缀中右括号×2-左括号的最小值 (geq 0),那么计入答案。

    转移直接枚举放左括号还是右括号。

    复杂度(o(n^3))

    当然由于n比较小,直接打表也行。

    #include<bits/stdc++.h>
    #define rep(q,a,b) for(int q=a,q##_end_=b;q<=q##_end_;++q)
    #define dep(q,a,b) for(int q=a,q##_end_=b;q>=q##_end_;--q)
    #define mem(a,b) memset(a,b,sizeof a )
    #define debug(a) cerr<<#a<<' '<<a<<"___"<<endl
    using namespace std;
    void in(int &r){
    	static char c;
    	r=0;
    	while(c=getchar(),!isdigit(c));
    	do r=(r<<1)+(r<<3)+(c^48);
    	while(c=getchar(),isdigit(c));
    }
    int T;
    namespace p_1{
    	const int mn=1e6+5;
    	char as[mn];
    	int sum[mn];
    	queue<int> had;
    	int cor[mn],tot[mn];
    	bool get(int len){
    		while(!had.empty())had.pop();
    		rep(q,1,len)cor[q]=0;
    		int last_zero=0;
    		rep(q,1,len){
    			int v=as[q]=='('?1:-1;
    			if(v==-1)had.push(q);
    			sum[q]=sum[q-1]+v;
    			if(sum[q]<0){
    				sum[q]=0;
    				if(had.size()<2){
    					return 0;
    				}
    				cor[had.front()]=1;
    				had.pop();
    				cor[had.front()]=2;
    				had.pop();
    			}
    			if(sum[q]==0)last_zero=q;
    		}
    		if(sum[len]>0){
    			tot[len+1]=0;
    			dep(q,len,last_zero+1)tot[q]=tot[q+1]+(as[q]==')');
    			int td=sum[len]<<1;
    			dep(q,len,last_zero+1)if(as[q]=='('){
    				if(td&1)cor[q]=1;
    				else cor[q]=2;
    				--td;
    				if((len-q+1-tot[q] +1)/2>tot[q])return 0;
    				if(!td)break;
    			}
    			return !td;
    		}
    		return 1;
    	}
    	void solve(){
    		in(T);
    		while(T--){
    		    scanf("%s",as+1);
    		    int len=strlen(as+1);
    		    if(get(len)){
    				rep(q,1,len){
    					if(cor[q]==0)putchar('G');
    					else if(cor[q]==1)putchar('B');
    					else putchar('R');
    				}
    				putchar('
    ');
    			}else puts("impossible");
    		}
    	}
    }
    namespace p_2{
    	
    	int ans[305]={0,0,1,2,2,6,12,18,43,86,148,326,652,1194,2531,5062,9578,19884,39768,76680,157236,314472,613440,1248198,2496396,4906266,9932707,19865414,39237478,79165646,158331292,313801154,631634323,263268639,509707998,43257469,86514938,72895660,288290012,576580024,551498904,962513721,925027435,204521844,634307677,268615347,287719520,559111350,118222693,578936427,105459291,210918582,360752402,920849461,841698915,421349166,985137176,970274345,96196738,666703791,333407575,448451120,71192847,142385694,391328273,82210164,164420328,697441626,75399225,150798450,177655189,77725370,155450740,578770998,806452500,612904993,342317187,437431531,874863062,166780006,649351541,298703075,764861307,105948983,211897966,169754380,332500687,665001374,648783808,296688714,593377428,43060831,684124175,368248343,973819030,849070862,698141717,982308804,88186365,176372730,959772055,320975583,641951166,825442333,311190079,622380158,765671696,14446067,28892134,262223145,966556598,933113189,520941027,287565710,575131420,666019185,263936054,527872108,39283492,877846547,755693087,433079969,737806887,475613767,203965075,701508060,403016113,922600280,277710517,555421034,408729101,377397802,754795604,250532053,528340400,56680793,124734442,232656836,465313672,714603167,631625056,263250105,52648990,389536240,779072480,641256163,302398795,604797590,697370162,632833340,265666673,626109777,298187773,596375546,406717000,515830626,31661245,524137426,667633864,335267721,338047842,390892123,781784246,93415445,65330389,130660778,151215664,822766849,645533691,833650616,380489231,760978462,54775313,491923347,983846694,322809267,940997512,881995017,596258099,507985218,15970429,557503950,859869218,719738429,474482700,767988978,535977949,635491203,387005395,774010790,702061186,253594815,507189630,31838831,822372294,644744581,231777149,215914547,431829094,482869402,576014681,152029355,369499245,244741222,489482444,95772722,952809165,905618323,304323137,304632041,609264082,102336119,335070266,670140532,858231094,960619772,921239537,859847032,56893721,113787442,360033502,982628521,965257035,849451750,439416129,878832258,991939394,464496385,928992770,267785589,802816545,605633083,763528731,474974661,949949322,864267253,946087508,892175009,476000768,273171027,546342054,550581443,469352643,938705286,624000951,673806443,347612879,434823692,233016716,466033432,103642988,440059594,880119188,788176043,40656596,81313192,286602731,202636014,405272028,733717711,472596468,945192936,553096598,892385168,784770329,912447619,707646096,415292185,526477156,861291715,722583423,111861393,588150125,176300243,301383510,244253166,488506332,629844702,421869639,843739278,290375226,384946885,769893770,95673275,473895679,947791358,891751001,164209639,328419278,62075416,175112411,350224822,934621064,806088783,612177559,897003764,948394637,896789267,953901352,418921686,837843372};
    	int dp[2][305][605];
    	const int mod=1e9+7;
    	void add(int &a,int b){
    		a=(a+b)%mod;
    	}
    	void calc(){
    		int ed=300;
    		dp[0][0][0]=1;
    		bool ok=0;
    		rep(q,0,ed){
    		    ok=!ok;
    		    mem(dp[ok],0);
    			rep(l,0,q){
    				int r=q-l;
    				rep(w,0,2*q){
    					if(r*2-l -w>=0)add(ans[q],dp[!ok][l][w]);
    					
    					if(l*2-r-1>=0)add(dp[ok][l][max(w,(r+1)*2-l)],dp[!ok][l][w]);
    					add(dp[ok][l+1][max(w,r*2-l-1)],dp[!ok][l][w]);
    				}
    			}
    		}
    	}
    	void solve(){
    		in(T);
    		int n;
    		while(T--){
    			in(n);
    			printf("%d
    ",ans[n]);
    		}
    	}
    }
    int main(){
    	freopen("parentrises.in","r",stdin);
    	freopen("parentrises.out","w",stdout);
    	int P;
    	in(P);
    	if(P==1)p_1::solve();
    	else p_2::solve();
    	return 0;
    }
    
  • 相关阅读:
    C#中|(位或)和||(逻辑或)
    VS快捷键(转)
    C# 3.0 新特性 学习(二):匿名类型、扩展方法
    Highcharts 如何添加基准线
    怎样用Diskpart进行分区
    命名空间别名限定符 (::)
    NDK下 将Platinum SDK 编译成so库 (android upnp)
    在native线程利用JNI 反射自定义类
    GithubClient(ANDROID)开源之旅(一) 初探GitHub
    基于Platinum库的DMR实现(android)
  • 原文地址:https://www.cnblogs.com/klauralee/p/11283704.html
Copyright © 2020-2023  润新知