2017.10.21离线赛总结

来源:互联网 发布:mac值是麻醉中什么 编辑:程序博客网 时间:2024/06/05 04:33

square ——2994

思路:强模拟…

lis ——2995

思路:dp,先算总方案数,再将对应得位置判一下。

paint ——3798

思路:看过题意,应该条件反射出二分答案,又因为n=2,也就是说,要么第1行画到i位置,第2行画到j位置,或者同时画到k位置。就很容易想到dp
每一次check时的dp,有很多是冗余的,便可预处理出来。这样达到的效果就应当于跳着画。

#include<bits/stdc++.h>#define REP(i,f,t) for(int i=(f),i##_end_=(t);i<=i##_end_;i++)#define DREP(i,f,t) for(int i=(f),i##_end_=(t);i>=i##_end_;i--)#define INF 0x3f3f3f3f#define LL long long#define N 20005#define M 105using namespace std;int n,m;LL tot;int A[2][N];struct p20{    int sum[3][N];    bool dp[200][200];     bool check(LL x){        memset(dp,0,sizeof(dp));        dp[0][0]=1;        REP(l,1,m)DREP(i,n,0)DREP(j,n,0){            if(!dp[i][j])continue;            if(i==j){                REP(k,i+1,n){                    if(sum[2][k]-sum[2][i]>x)break;                    dp[k][k]=1;                }            }            REP(k,i+1,n){                if(sum[0][k]-sum[0][i]>x)break;                dp[k][j]=1;            }            REP(k,j+1,n){                if(sum[1][k]-sum[1][j]>x)break;                dp[i][k]=1;             }        }        return dp[n][n];    }    void solve(){        REP(i,0,1)REP(j,1,n)sum[i][j]+=sum[i][j-1]+A[i][j];        REP(i,1,n)sum[2][i]+=sum[0][i]+sum[1][i];        LL L=tot/m,R=tot,ans;        while(L<=R){            LL mid=(L+R)>>1;            if(check(mid))ans=mid,R=mid-1;            else L=mid+1;        }        cout<<ans<<endl;    }}p20;struct p40{    LL sum[3][505];    bool dp[750][750];    bool check(LL mx){        memset(dp,0,sizeof(dp));        dp[0][0]=1;        REP(l,1,m)DREP(i,n,0)DREP(j,n,0){            if(!dp[i][j])continue;            if(i==j){                int k=upper_bound(sum[2]+i,sum[2]+n+1,sum[2][i]+mx)-sum[2]-1;                dp[k][k]=1;            }            int k=upper_bound(sum[0]+i,sum[0]+n+1,sum[0][i]+mx)-sum[0]-1;            if(k>j)dp[j][j]=1;            dp[k][j]=1;            k=upper_bound(sum[1]+j,sum[1]+n+1,sum[1][j]+mx)-sum[1]-1;            if(k>i)dp[i][i]=1;            dp[i][k]=1;        }        return dp[n][n];    }    void solve(){        REP(i,0,1)REP(j,1,n)sum[i][j]+=sum[i][j-1]+A[i][j];        REP(i,1,n)sum[2][i]+=sum[1][i]+sum[0][i];        LL L=tot/m,R=tot,ans=0;        while(L<=R){            LL mid=(L+R)>>1;            if(check(mid))ans=mid,R=mid-1;            else L=mid+1;        }        cout<<ans<<endl;    }}p40;struct p80{    int dp[N];    bool check(LL x){        memset(dp,INF,sizeof(dp));        dp[0]=0;        REP(i,1,n){            int s0=0,s1=0,cnt=0;            DREP(j,i,1){                if(s0+A[0][j]>x)cnt++,s0=0;                if(s1+A[1][j]>x)cnt++,s1=0;                s0+=A[0][j],s1+=A[1][j];                dp[i]=min(dp[i],dp[j-1]+cnt+(s0>0)+(s1>0));            }            int s2=0;cnt=0;            DREP(j,i,1){                if(s2+A[0][j]+A[1][j]>x)cnt++,s2=0;                s2+=A[0][j]+A[1][j];                if(s2>x)break;                dp[i]=min(dp[i],dp[j-1]+cnt+(s2>0));            }            if(dp[i]>m)return 0;        }        return dp[n]<=m;    }    void solve(){        LL L=tot/m,R=tot,ans=0;        while(L<=R){            LL mid=(L+R)>>1;            if(check(mid))ans=mid,R=mid-1;            else L=mid+1;        }        cout<<ans<<endl;    }}p80;struct p100{    int dp[N],sum[3][N],nxt[3][N];    void chkmin(int &x,int y){if(x>y)x=y;}    bool check(LL x){        memset(dp,63,sizeof(dp));        dp[0]=0;        REP(i,0,2){            int L=1,R=1;            while(L<=n){                while(R<=n && sum[i][R]-sum[i][L-1]<=x)R++;                nxt[i][L]=R-1;                L++;            }        }        REP(i,0,n-1){            if(dp[i]==INF)continue;            int cnt=2,a=nxt[0][i+1],b=nxt[1][i+1];            chkmin(dp[nxt[2][i+1]],dp[i]+1);            while(a!=n || b!=n){                chkmin(dp[min(a,b)],dp[i]+cnt);                if(a<b)a=nxt[0][a+1];                else b=nxt[1][b+1];                cnt++;                if(cnt+dp[i]>m)break;            }            if(a==n && b==n)chkmin(dp[n],dp[i]+cnt);            if(dp[n]<=m)return 1;        }        return dp[n]<=m;    }    void solve(){        REP(i,0,1)REP(j,1,n)sum[i][j]+=sum[i][j-1]+A[i][j];        REP(i,1,n)sum[2][i]+=sum[1][i]+sum[0][i];               LL L=1,R=tot,ans=0;        while(L<=R){            LL mid=(L+R)>>1;            if(check(mid))ans=mid,R=mid-1;            else L=mid+1;        }        cout<<ans<<endl;    }}p100;int main(){    scanf("%d%d",&n,&m);    REP(i,0,1)REP(j,1,n)scanf("%d",&A[i][j]),tot+=A[i][j];    p100.solve();     return 0;}

小结:今天第一题题目看错,我也无fuck可说…总体就是炸了。

原创粉丝点击