• BZOJ4676: Xor-Mul棋盘


    BZOJ4676: Xor-Mul棋盘

    https://lydsy.com/JudgeOnline/problem.php?id=4675

    分析:

    • 就是个简单的拆位DP,不要想得太复杂
    • 位与位之间互不影响,对每一位分别求然后加和
    • (f[i][j])表示前(i)列,第(i)列的状态是(j)的答案。

    代码:

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    typedef long long ll;
    #define N 10
    #define M 10050
    int n,m;
    int a[N][M],b[N][M],c1[N][M],c2[N][M],c3[M];
    ll f[M][40],cal[M][40],cal2[M][40];
    char buf[100000],*p1,*p2;
    #define nc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++)
    int rd() {
    	int x=0; char s=nc();
    	while(s<'0') s=nc();
    	while(s>='0') x=(((x<<2)+x)<<1)+s-'0',s=nc();
    	return x;
    }
    template <typename T> void chkmin(T &x,T y) {x=x<y?x:y;}
    ll calc(int p,int c,int s) {
    	int i;
    	ll re=0;
    	if(((s>>(n-1))&1) != (s&1)) {
    		re+=ll(1<<p)*c3[c];
    	}
    	for(i=1;i<=n;i++) {
    		if( ((s>>(i-1))&1) != ((a[i][c]>>p)&1)) {
    			re+=ll(1<<p)*b[i][c];
    		}
    		if(i!=n) if( ((s>>(i-1))&1) != ((s>>i)&1)) {
    			re+=ll(1<<p)*c2[i][c];
    		}
    	}
    	return re;
    }
    ll calc2(int p,int c,int s) {
    	int i;
    	ll re=0;
    	for(i=1;i<=n;i++) {
    		if(s&(1<<(i-1))) {
    			re+=ll(1<<p)*c1[i][c];
    		}
    	}
    	return re;
    }
    int main() {
    	scanf("%d%d",&n,&m);
    	int i,j,k,p,l=0,mx=0;
    	for(i=1;i<=n;i++) {
    		for(j=1;j<=m;j++) {
    			a[i][j]=rd();
    			mx=max(mx,a[i][j]);
    		}
    	}
    	for(i=1;i<=n;i++) {
    		for(j=1;j<=m;j++) {
    			b[i][j]=rd();
    		}
    	}
    	for(i=1;i<=n;i++) {
    		for(j=1;j<m;j++) {
    			c1[i][j]=rd();
    		}
    	}
    	for(i=1;i<n;i++) {
    		for(j=1;j<=m;j++) {
    			c2[i][j]=rd();
    		}
    	}
    	
    	for(i=1;i<=m;i++) c3[i]=rd();
    	int mask=(1<<n)-1;
    
    	ll ans=0;
    	for(p=0;(1<<p)<=mx;p++) {
    		for(i=1;i<=m;i++) {
    			for(j=0;j<=mask;j++) {
    				cal[i][j]=calc(p,i,j);
    				if(i!=m) cal2[i][j]=calc2(p,i,j);
    			}
    		}
    		memset(f,0x3f,sizeof(f));
    		for(i=0;i<=mask;i++) {
    			f[1][i]=cal[1][i];
    		}
    		for(i=1;i<m;i++) {
    			for(j=0;j<=mask;j++) if(f[i][j]<1ll<<60) {
    				ll tmp=f[i][j];
    				for(k=0;k<=mask;k++) {
    					chkmin(f[i+1][k],tmp+cal[i+1][k]+cal2[i][j^k]);
    				}
    			}
    		}
    		ll mn=1ll<<60;
    		for(i=0;i<=mask;i++) chkmin(mn,f[m][i]);
    		ans+=mn;
    	}
    	printf("%lld
    ",ans);
    }
    
    
    
  • 相关阅读:
    CMD与bat操作
    XmlHelper XML通用类
    Regex正则表达式扩展
    LONG数据类型转换为VARCHAR2并相互转换
    CLOB数据类型截取SUBSTR_按开始位置偏移量
    12c rac On redhat 7
    DML_DDL_触发器
    Linux平台 Oracle 18c RAC安装
    hadoop 透明加密
    Poco::Crypto--加解密_RSA
  • 原文地址:https://www.cnblogs.com/suika/p/10051660.html
Copyright © 2020-2023  润新知