码迷,mamicode.com
首页 > 其他好文 > 详细

【JZOJ5738】【20190706】锁屏杀

时间:2019-07-07 17:19:13      阅读:161      评论:0      收藏:0      [点我收藏+]

标签:mem   技术   时间   void   open   ++   %s   const   end   

题目

技术图片

技术图片

技术图片

$n \le 2000 $

题解

  • \(B\)的数字可以对1440取模,对三个图分别进行\(dp\)即可
  • 时间复杂度\(O(n\times 1440 \times 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]=g[n+1];
}
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;
}

【JZOJ5738】【20190706】锁屏杀

标签:mem   技术   时间   void   open   ++   %s   const   end   

原文地址:https://www.cnblogs.com/Paul-Guderian/p/11146659.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!