• 【洛谷 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();
    }
    
  • 相关阅读:
    SVN自动更新测试服务器工作副本(C#写winform程序实现)
    两台服务器上SQL Server数据库数据互操作示例
    ASP.NET根据URL生成网页缩略图示例程序(C#语言)
    Flutter Widget API
    BPM、BPMN、BPMN2.0概念介绍
    H5多图上传调研
    lIUNX如何加载U盘,光盘
    如何解决exchange2003被中继的问题?(网上转载)
    window无法安装服务
    如何在WORD里面插入不同的页眉和页脚
  • 原文地址:https://www.cnblogs.com/stargazer-cyk/p/12328496.html
Copyright © 2020-2023  润新知