• 【JZOJ5738】【20190706】锁屏杀


    题目

    img

    img

    img

    $n le 2000 $

    题解

    • (B)的数字可以对1440取模,对三个图分别进行(dp)即可
    • 时间复杂度(O(n imes 1440 imes 10))

    Code

    #include<bits/stdc++.h>
    #define il inline 
    using namespace std;
    const int N=2100,P=1440;
    int n,cnt[128],F[P],G1[P],G2[P],mp[N],a[N][10];
    char S[7][N];
    int num[10][5]={
    	{127,65,65,127,0},
    	{0,0,0,127,0},
    	{121,73,73,79,0},
    	{73,73,73,127,0},
    	{15,8,8,127,0},
    	{79,73,73,121,0},
    	{127,73,73,121,0},
    	{1,1,1,127,0},
    	{127,73,73,127,0},
    	{79,73,73,127,0}
    };
    il void upd(int&x,int y){if(x>y)x=y;}
    il int get(int x,int y){
    	int re=0;
    	for(int i=0;i<5;++i)re+=cnt[mp[x+i]^num[y][i]];
    	return re;
    }
    void init(){
    	scanf("%d",&n);
    	for(int i=6;~i;--i)scanf("%s",S[i]+1);
    	
    	for(int i=1,x;i<=n;mp[i++]=x)
    	for(int j=x=0;j<7;++j)
    		x=x<<1|(S[j][i]=='X');
    	mp[n+1]=0;
    
    	memset(a,1,sizeof(a));
    	for(int i=1;i<=n-3;++i)
    	for(int j=0;j<10;++j)
    		a[i][j]=get(i,j);
    }
    void solve2(int *re){
    	static int f[N][P],g[N],s[N];
    	memset(f,1,sizeof(f));
    	memset(g,1,sizeof(g));
    	memset(s,1,sizeof(s));
    	init();
    	
    	s[0]=0;
    	for(int i=0;i<=n;++i){
    		int t=cnt[mp[i+1]];
    		s[i+1]=s[i]+t;
    		
    		upd(g[i+1],g[i]+t);
    		upd(g[i+5],s[i]+a[i+1][0]);
    		for(int j=1;j<10;++j){
    			upd(f[i+5][j],s[i]+a[i+1][j]);
    		}	
    		for(int j=0;j<P;++j){
    			upd(f[i+1][j],f[i][j]+t);
    			for(int k=0;k<10;++k){
    				upd(f[i+5][(j*10+k)%P],f[i][j]+a[i+1][k]);
    			}
    		}
    
    	}
    	
    	for(int i=1;i<P;++i)re[i]=f[n+1][i];
    	re[0]=min(g[n+1],f[n+1][0]);
    }
    void solve1(int *re){
    	static int l[N][3],L[N][24],r[N][10],R[N][60],s[N];
    	init();
    	memset(l,1,sizeof(l));
    	memset(r,1,sizeof(r));
    	memset(L,1,sizeof(L));
    	memset(R,1,sizeof(R));
    	memset(s,1,sizeof(s));
    		
    	s[0]=0;
    	for(int i=0;i<=n;++i){
    		int t=cnt[mp[i+1]];
    		s[i+1]=s[i]+t;
    		for(int j=0;j<3;++j){
    			upd(l[i+1][j],l[i][j]+t);
    			upd(l[i+5][j],s[i]+a[i+1][j]);
    		}
    		for(int j=0;j<10;++j){
    			upd(L[i+1][j],L[i][j]+t);
    			upd(L[i+1][10+j],L[i][10+j]+t);
    			upd(L[i+5][j],l[i][0]+a[i+1][j]);
    			upd(L[i+5][10+j],l[i][1]+a[i+1][j]);
    		}
    		for(int j=0;j<4;++j){
    			upd(L[i+1][20+j],L[i][20+j]+t);
    			upd(L[i+5][20+j],l[i][2]+a[i+1][j]);
    		}
    	}
    	
    	s[n+1]=s[n+2]=0;
    	for(int i=n;i;--i){
    		int t=cnt[mp[i]];
    		s[i]=s[i+1]+t;
    		for(int j=0;j<10;++j){
    			upd(r[i][j],r[i+1][j]+t);
    			upd(r[i][j],a[i][j]+s[i+5]);
    		}
    		for(int j=0;j<6;++j)
    		for(int k=0;k<10;++k){
    			int x=10*j+k;
    			upd(R[i][x],R[i+1][x]+t);
    			upd(R[i][x],a[i][j]+r[i+5][k]);
    		}
    	}
    
    	for(int i=0;i<24;++i)
    	for(int j=0;j<60;++j){
    		int t=0x3f3f3f3f;
    		for(int k=1;k<=n+1;++k)
    			upd(t,L[k-1][i]+R[k+2][j]+cnt[mp[k]^20]+cnt[mp[k+1]]);
    		re[i*60+j]=t;
    	}
    }
    void getans(){
    	int re=0x3f3f3f3f;
    	for(int i=0;i<P;++i)
    	for(int j=0;j<P;++j){
    		int t=j-i;if(t<0)t+=P;
    		upd(re,G1[i]+G2[j]+F[t]);
    	}
    	cout<<re<<endl;
    }
    int main(){
    	freopen("joke.in","r",stdin);
    	freopen("joke.out","w",stdout);
    	for(int i=1;i<128;++i)cnt[i]=cnt[i>>1]+(i&1);
    	solve1(G1);
    	solve2(F);
    	solve1(G2);
    	getans();
    	return 0;
    }
    
  • 相关阅读:
    uestc1307 windy数 ——数位DP入门题
    2013年4月3日 小雨,阴
    hdu1202 The calculation of GPA ——水题
    zoj 3693 Happy Great BG
    hdu 2035 人见人爱A^B ——同余的简单性质
    zoj2913 Bus Pass ——BFS入门题
    一个bug,持续更新……
    zoj 3406 Another Very Easy Task
    poj 1995 Raising Modulo Numbers ——快速幂
    hdu 1059 Dividing ——多重背包复习
  • 原文地址:https://www.cnblogs.com/Paul-Guderian/p/11146659.html
Copyright © 2020-2023  润新知