zoukankan      html  css  js  c++  java
  • 【洛谷 P5289】【十二省联考】—皮配(背包dp)

    传送门

    分成三类
    不受影响的城市以及城市的学校
    受影响的城市里不受影响的学校
    受影响的学校

    第一类可以直接O(nc)O(nc)分别dpdp阵营和派系后乘起来
    第二类可以和第一类一起dpdp派系但不考虑阵营
    第三类暴力O(kc2)dpO(kc^2)dp即可

    #include<bits/stdc++.h>
    using namespace std;
    const int RLEN=1<<20|1;
    inline char gc(){
        static char ibuf[RLEN],*ib,*ob;
        (ob==ib)&&(ob=(ib=ibuf)+fread(ibuf,1,RLEN,stdin));
        return (ob==ib)?EOF:*ib++;
    }
    #define gc getchar
    inline int read(){
        char ch=gc();
        int res=0,f=1;
        while(!isdigit(ch))f^=ch=='-',ch=gc();
        while(isdigit(ch))res=(res+(res<<2)<<1)+(ch^48),ch=gc();
        return f?res:-res;
    }
    #define ll long long
    #define re register
    #define pii pair<int,int>
    #define fi first
    #define se second
    #define pb push_back
    #define cs const
    #define bg begin
    #define poly vector<int>  
    cs int mod=998244353;
    inline int add(int a,int b){return (a+=b)>=mod?a-mod:a;}
    inline void Add(int &a,int b){(a+=b)>=mod?a-=mod:0;}
    inline int dec(int a,int b){return (a-=b)<0?a+mod:a;}
    inline void Dec(int &a,int b){(a-=b)<0?a+=mod:0;}
    inline int mul(int a,int b){return 1ll*a*b%mod;}
    inline void Mul(int &a,int b){a=1ll*a*b%mod;}
    inline int ksm(int a,int b,int res=1){for(;b;b>>=1,Mul(a,a))(b&1)&&(Mul(res,a),1);return res;}
    inline int Inv(int x){return ksm(x,mod-2);}
    inline void chemx(int &a,int b){a<b?a=b:0;}
    inline void chemn(int &a,int b){a>b?a=b:0;}
    cs int N=1005,M=2505;
    int n,c,c0,c1,d0,d1,K;
    int bel[N],val[N],s[N],sum[N],req[N],ban[N],vis[N];
    vector<int> lim[N],city,sco;
    int f[M],g[M],p[M][M],tp1[M][M],tp2[M][M];
    inline void calc_p(){
    	int tot1=0,tot2=0,r1=0,r2=0;
    	p[0][0]=1;
    	for(int o=1;o<=c;o++){
    		if(!lim[o].size())continue;
    		for(int i=min(tot1,c0);~i;i--)
    		for(int j=min(tot2,d0);~j;j--)
    		tp1[i][j]=tp2[i][j]=p[i][j];
    		for(int &x:lim[o]){
    			tot2+=val[x];
    			int t0=ban[x]!=0,t1=ban[x]!=1,t2=ban[x]!=2,t3=ban[x]!=3;
    			for(int i=min(tot1,c0);~i;i--)
    			for(int j=min(tot2,d0);~j;j--)
    			if(j>=val[x]){
    				tp1[i][j]=add(tp1[i][j]*t1,tp1[i][j-val[x]]*t0);
    				tp2[i][j]=add(tp2[i][j]*t3,tp2[i][j-val[x]]*t2);
    				chemx(r1,i),chemx(r2,j);
    			}
    			else tp1[i][j]=tp1[i][j]*t1,tp2[i][j]=tp2[i][j]*t3,chemx(r1,i),chemx(r2,j);;
    		}
    		tot1+=sum[o];
    		for(int i=min(tot1,c0);~i;i--)
    		for(int j=min(tot2,d0);~j;j--)
    		if(i>=sum[o])p[i][j]=add(tp1[i-sum[o]][j],tp2[i][j]),chemx(r1,i),chemx(r2,j);
    		else p[i][j]=tp2[i][j],chemx(r1,i),chemx(r2,j);;
    	}
    	for(int i=min(tot1,c0);~i;i--)
    	memset(tp1[i],0,sizeof(int)*(min(tot2,d0)+1)),memset(tp2[i],0,sizeof(int)*(min(tot2,d0)+1));
    }
    inline void calc_f(){
    	memset(f,0,sizeof(int)*(c0+1));
    	f[0]=1;int tot=0,res;
    	for(int &x:city){
    		tot+=x;
    		for(int j=min(c0,tot);~j;j--){
    			res=0;
    			if(j>=x)Add(res,f[j-x]);
    			if(tot-j<=c1)Add(res,f[j]);
    			f[j]=res;
    		}
    	}
    }
    inline void calc_g(){
    	memset(g,0,sizeof(int)*(d0+1));
    	g[0]=1;int tot=0,res;
    	for(int &x:sco){
    		tot+=x;
    		for(int j=min(d0,tot);~j;j--){
    			res=0;
    			if(j>=x)Add(res,g[j-x]);
    			if(tot-j<=d1)Add(res,g[j]);
    			g[j]=res;
    		}
    	}
    }
    inline void solve(){
    	n=read(),c=read();int tot=0;
    	c0=read(),c1=read(),d0=read(),d1=read();
    	for(int i=1;i<=n;i++)
    		bel[i]=read(),val[i]=read(),tot+=val[i],sum[bel[i]]+=val[i];
    	K=read();
    	for(int i=1;i<=K;i++){
    		int pos=read(),r=read();
    		req[bel[pos]]=1,ban[pos]=r,vis[pos]=1;
    		lim[bel[pos]].pb(pos);
    	}
    	for(int i=1;i<=n;i++)if(!vis[i])s[bel[i]]+=val[i],sco.pb(val[i]);
    	for(int i=1;i<=c;i++)if(!req[i]&&s[i])city.pb(s[i]);
    	calc_f();
    	calc_g();
    	calc_p();
    	int res=0;
    	for(int i=1;i<=c0;i++)Add(f[i],f[i-1]);
    	for(int i=1;i<=d0;i++)Add(g[i],g[i-1]);
    	for(int i=0;i<=c0;i++)
    	for(int j=0;j<=d0;j++){
    		int tmp=1;
    		if(c0-i>=tot-c1-i)Mul(tmp,dec(f[c0-i],tot-c1-i-1>=0?f[tot-c1-i-1]:0));
    		if(d0-j>=tot-d1-j)Mul(tmp,dec(g[d0-j],tot-d1-j-1>=0?g[tot-d1-j-1]:0));
    		Add(res,mul(tmp,p[i][j]));
    	}
    	cout<<res<<'
    ';
    	memset(p,0,sizeof(p));
    	for(int i=1;i<=n;i++)vis[i]=val[i]=bel[i]=ban[i]=0;
    	for(int i=1;i<=c;i++)sum[i]=s[i]=req[i]=0,lim[i].clear();
    	sco.clear(),city.clear();
    }
    int main(){
    	int T=read();
    	while(T--)solve();
    }
    
  • 相关阅读:
    角色扮演游戏引擎的设计原理
    游戏服务器架构
    小谈网络游戏同步
    What is the single most influential book every programmer should read?
    Research Scientists and Engineers
    关于为什么不推荐使用用户定义表类型的说明
    程序员必须遵守的编程原则
    CacheStrategy缓存
    正能量
    MEF 和 MAF
  • 原文地址:https://www.cnblogs.com/stargazer-cyk/p/12328497.html
Copyright © 2011-2022 走看看