• 8.10 NOI 模拟赛 ldysb dp套dp dp


    LINK:ldysb

    avatar
    avatar

    其实我不会这道题的正解 题解就来了一句dp套dp 只有STD的我 无能为力.

    这里写主要是因为考试的时候连40分的暴力都打不出来.

    先考虑20分的暴力.

    可以得知 每次必然是从 3,5,7...这些地方点的.

    而且顺序满足 点过后面的前面就点不了了.

    所以可以(f_{i,j})表示前i个能否形成字符j.

    暴力枚举转移就是n^2的.

    考虑怎么线性判断.

    从前往后 那么就有因为不知道后面的给的是0还是1 而无法判断.

    我们考虑设计状态来解决这个情况.

    想解决这个问题 需要暴力枚举下一位是什么,有(f_{i,j})表示 到了第i个位置下一位是j 那么前面的能变成什么.

    然后可能变成0/1 再开一维记录即可.

    这样就把所有的情况给压缩起来了.

    算是一个套路吧 状态中暴力枚举下一次的状态来进行dp.

    score 40
    //#include<bits/stdc++.h>
    #include<iostream>
    #include<cstdio>
    #include<ctime>
    #include<cctype>
    #include<queue>
    #include<deque>
    #include<stack>
    #include<iostream>
    #include<iomanip>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<ctime>
    #include<cmath>
    #include<cctype>
    #include<cstdlib>
    #include<queue>
    #include<deque>
    #include<stack>
    #include<vector>
    #include<algorithm>
    #include<utility>
    #include<bitset>
    #include<set>
    #include<map>
    #define ll long long
    #define db double
    #define INF 1000000000
    #define inf 1000000000000000ll
    #define ldb long double
    #define pb push_back
    #define put_(x) printf("%d ",x);
    #define get(x) x=read()
    #define gt(x) scanf("%d",&x)
    #define gi(x) scanf("%lf",&x)
    #define put(x) printf("%d
    ",x)
    #define putl(x) printf("%lld
    ",x)
    #define rep(p,n,i) for(RE int i=p;i<=n;++i)
    #define go(x) for(int i=lin[x],tn=ver[i];i;tn=ver[i=nex[i]])
    #define fep(n,p,i) for(RE int i=n;i>=p;--i)
    #define vep(p,n,i) for(RE int i=p;i<n;++i)
    #define pii pair<int,int>
    #define mk make_pair
    #define RE register
    #define P 13331ll
    #define gf(x) scanf("%lf",&x)
    #define pf(x) ((x)*(x))
    #define uint unsigned long long
    #define ui unsigned
    #define EPS 1e-5
    #define sq sqrt
    #define S second
    #define F first
    #define mod 1000000007
    #define md 998244353
    #define max(x,y) ((x)<(y)?y:x)
    #define l(i) t[i].l
    #define r(i) t[i].r
    #define mx(i) t[i].mx
    #define w(i) t[i].w
    #define zz p<<1
    #define yy p<<1|1
    using namespace std;
    char buf[1<<15],*fs,*ft;
    inline char getc()
    {
    	return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:*fs++;
    }
    inline int read()
    {
    	RE int x=0,f=1;RE char ch=getc();
    	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getc();}
    	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getc();}
    	return x*f;
    }
    inline ll Read()
    {
    	RE ll x=0,f=1;RE char ch=getc();
    	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getc();}
    	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getc();}
    	return x*f;
    }
    const int MAXN=100010;
    int T,n;
    char a[MAXN];
    int w[8];
    int b[MAXN];
    int f[MAXN][2][2];
    int main()
    {
    	freopen("ldysb.in","r",stdin);
    	freopen("ldysb.out","w",stdout);
    	scanf("%d",&T);
    	while(T--)
    	{
    		scanf("%s",a+1);
    		
    		w[0]=a[1]-'0';
    		w[4]=a[2]-'0';
    		w[2]=a[3]-'0';
    		w[6]=a[4]-'0';
    		w[1]=a[5]-'0';
    		w[5]=a[6]-'0';
    		w[3]=a[7]-'0';
    		w[7]=a[8]-'0';
    		scanf("%s",a+1);
    		n=strlen(a+1);
    		
    		if(n==1&&a[1]=='1'){puts("1");continue;}
    		if(n<=2){puts("0");continue;}		
    		rep(1,n,i)
    		{
    			if(a[i]=='?')return 0;
    			f[i][0][0]=f[i][0][1]=0;
    			f[i][1][0]=f[i][1][1]=0;
    			b[i]=a[i]-'0';
    		}
    		f[2][0][w[b[1]<<2|b[2]<<1]]=1;
    		f[2][1][w[b[1]<<2|b[2]<<1|1]]=1;
    		for(int i=4;i<=n;i+=2)
    		{
    			//merge
    			int ww;
    			rep(0,1,j)
    			{
    				if(!f[i-2][b[i-1]][j])continue;
    				//j a[i]
    				f[i][0][w[j<<2|b[i]<<1]]=1;
    				f[i][1][w[j<<2|b[i]<<1|1]]=1;
    			}
    			//not merge
    			rep(0,1,j)
    			{
    				// a[i-1] a[i] j
    				ww=w[b[i-1]<<2|b[i]<<1|j];
    				rep(0,1,k)if(f[i-2][ww][k])f[i][j][k]=1;
    			}
    		}
    		put(f[n-1][b[n]][1]);
    	}
    	return 0;
    }
    

    统计方案数需要dp套dp 学过但不太会 自闭.

    std
    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef pair<int,int> PII;
    const int maxn=100010,mod=998244353;
    #define MP make_pair
    #define lson o<<1,l,mid
    #define rson o<<1|1,mid+1,r
    #define FOR(i,a,b) for(int i=(a);i<=(b);i++)
    #define ROF(i,a,b) for(int i=(a);i>=(b);i--)
    #define MEM(x,v) memset(x,v,sizeof(x))
    inline int read(){
        int x=0,f=0;char ch=getchar();
        while(ch<'0' || ch>'9') f|=ch=='-',ch=getchar();
        while(ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();
        return f?-x:x;
    }
    int n,p[maxn],s[maxn],to[16][2][2],f[maxn][16];
    char str[maxn];
    inline void qmo(int &x){x+=(x>>31?mod:0);}
    void solve(){
    	scanf("%s",str);
    	FOR(i,0,7) p[i]=str[i]-'0';
    	FOR(i,0,16) FOR(s1,0,1) FOR(s2,0,1){
    		int s=0;
    		FOR(k,0,1){
    			s|=((i>>(k<<1|s1))&1)<<(p[s2<<1|k]<<1);
    			s|=((i>>(k<<1|s1))&1)<<(p[s2<<1|k|4]<<1|1);
    			s|=((i>>(k<<1|p[s2<<1|s1]))&1)<<(k<<1);
    			s|=((i>>(k<<1|p[s2<<1|s1|4]))&1)<<(k<<1|1);
    		}
    		to[i][s1][s2]=s;
    	}
    	scanf("%s",str+1);
    	n=strlen(str+1);
    	FOR(i,1,n) s[i]=(str[i]=='?'?-1:str[i]-'0');
    	f[0][9]=1;
    	for(int i=0;i+2<=n;i+=2) FOR(j,0,15){
    		if (s[i+1]!=1 && s[i+2]!=1) qmo(f[i+2][to[j][0][0]]+=f[i][j]-mod);
    		if (s[i+1]!=0 && s[i+2]!=1) qmo(f[i+2][to[j][1][0]]+=f[i][j]-mod);
    		if (s[i+1]!=1 && s[i+2]!=0) qmo(f[i+2][to[j][0][1]]+=f[i][j]-mod);
    		if (s[i+1]!=0 && s[i+2]!=0) qmo(f[i+2][to[j][1][1]]+=f[i][j]-mod);
    	}
    	int ans=0;
    	FOR(i,0,15){
    		if (s[n]!=1 && ((i>>2)&1)) qmo(ans+=f[n-1][i]-mod);
    		if (s[n]!=0 && ((i>>3)&1)) qmo(ans+=f[n-1][i]-mod);
    	}
    	printf("%d
    ",ans);
    	MEM(f,0);
    }
    int main(){
    	int T=read();
    	while(T--) solve();
    }
    
  • 相关阅读:
    ubuntu14.04显卡驱动问题(amd5600k集显7650d)
    win7 ubuntu 14.04双系统安装
    func_num_args, func_get_arg, func_get-args 的区别与用法
    wamp2.5版本64位403forbidden问题
    mysql根据汉字拼音排序查询
    php判断浏览器语言
    php批量下载文件
    php搜索分页
    把ZenCart在线商店搭建到本地
    livezilla账号或密码修改方法
  • 原文地址:https://www.cnblogs.com/chdy/p/13485709.html
Copyright © 2020-2023  润新知