zoukankan      html  css  js  c++  java
  • csp-s模拟测试98「装饰·午餐」

    装饰

    题解

    其实是挺好的一道题

    正着实在不好做,还要考虑当前点是否可以传递,

    可以提前把整个链都处理出来,例如第一秒点灯把整条链都染上色

    然而你不知道终止时间

    枚举终止时间即可

    算是时光倒流

    还有,感谢wwb_ape

    代码

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define A 111
    ll sta[A],light[A],qw[A],fa[A],ff[35][35],f[35][1<<17|1];
    ll vis[20];
    ll n,ans=0x3f3f3f3f,top,mudi;
    int main(){
        freopen("decoration.in","r",stdin);
        freopen("decoration.out","w",stdout);
        scanf("%lld",&n);
        for(ll i=2;i<=n;i++)
            scanf("%lld",&fa[i]);
        for(ll i=1;i<=n;i++){
            scanf("%lld",&qw[i]);
            if(qw[i]==1) mudi|=1<<(i-1);
        }
        ll maxn=(1<<n)-1;
        fa[1]=0;
        for(ll i=1;i<=32;i++){
            for(ll j=1;j<=n;j++){
                ll cnt=0,now=j,tot=n-i;
                while(cnt<=tot&&now!=0){
                    cnt++;
                    ff[i][j]|=1<<(now-1);
    //                printf("ff[%lld][%lld]=%lld now=%lld
    ",i,j,ff[i][j],now);
                    now=fa[now];
                }
            }
        }
        f[n+1][0]=1;
        for(ll i=n;i>=1;i--){
            for(ll j=0;j<=maxn;j++){
                if(!f[i+1][j]) continue ;
                for(ll k=1;k<=n;k++){
                    f[i][j^ff[i][k]]|=f[i+1][j];
    //                printf("f[%lld][%lld]=%lld i+1=%lld j=%lld
    ",i,j^ff[i][k],f[i+1][j],i+1,j);
                }
                f[i][j]|=f[i+1][j];
    //            printf("f[%lld][%lld]=%lld
    ",i,j,f[i][j]);
    //            printf("mudi=%lld
    ",mudi);
                if(f[i][mudi]){
                    printf("%lld
    ",n-i+1);
                    return 0;
                }
            }
        }
    }
    View Code

    午餐

    题解

    考场真是什么也没想出来

    暴力都没打对,真是没救了

    还好我现在稍微会了一点

    有一个奇怪的子任务:不存在确定没有学会毒瘤算法的同学。

    看上去这个子任务给的性质好像没什么用

    我们还是可以推一推

    贪心取L即可

    证明感性理解一下

    于是f[x]=min(f[x],L)

    最短路形式,可以用最短路转移

    然后将这个子任务推广

    如果存在没有学会毒瘤算法的同学就是相当于给上述转移加了一个限制条件

    例如

    现有wwb,whs二人

    已知wwb学习毒瘤算法时间在>R,那么就意味着这次吃饭时whs也不会毒瘤算法

    仍然贪心考虑

    whs和wwb二人吃饭于L,然后whs在L+1学会毒瘤算法,就满足限制了

    于是lim[x]=max(L+1)

    先把lim算出来,再转移f就可以了

    代码

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define A 1111111
    ll n,m,tot;
    ll vis[A],mn[A],mx[A],head[A],nxt[A],ver[A],dis[A],flag[A],lst[A],lim[A];
    struct node{
        ll x,y,l,r;
        node(){}
        node(const ll &a,const ll &b,const ll &c,const ll &d){x=a,y=b,l=c,r=d;}
    }u[A];
    void add(ll x,ll y,ll minn,ll maxx){
        nxt[++tot]=head[x],ver[tot]=y,head[x]=tot,mn[tot]=minn,mx[tot]=maxx;
    }
    void pre_spfa(){
        deque<ll> q;
        for(ll i=1;i<=n;i++){
            scanf("%lld",&lst[i]);
            if(lst[i]==-1) lim[i]=1e9+7,vis[i]=1,q.push_back(i);
            else vis[i]=0;
        }
        while(!q.empty()){
            ll x=q.front();q.pop_front();
            vis[x]=0;
            for(ll i=head[x];i;i=nxt[i]){
                ll y=ver[i],minn=mn[i],maxx=mx[i];
                if(lim[x]>maxx){
                    if(lim[y]<minn+1){
                        lim[y]=minn+1;
                        if(!vis[y]){
                            vis[y]=1;
                            q.push_back(y);
                        }
                    }
                }
            }
        }
    }
    void spfa(){
        deque<ll> q;
        for(ll i=1;i<=n;i++)
            vis[i]=0,dis[i]=1e9+7;
        dis[1]=0;q.push_back(1);
        while(!q.empty()){
            ll x=q.front();q.pop_front();
            vis[x]=0;
            for(ll i=head[x];i;i=nxt[i]){
                ll y=ver[i],minn=mn[i],maxx=mx[i],g=max(max(lim[y],minn),dis[x]);
    //            printf("y=%lld minn=%lld maxx=%lld g=%lld
    ",y,minn,maxx,g);
                if(dis[y]>g&&g<=maxx){
                    dis[y]=g;
    //                printf("dis[%lld]=%lld
    ",y,dis[y]);
                    if(!vis[y]){
                        vis[y]=1;
                        q.push_back(y);
                    }
                }
            }
        }
    }
    int main(){
        freopen("lunch.in","r",stdin);
        freopen("lunch.out","w",stdout);
        scanf("%lld%lld",&n,&m);
        for(ll i=1;i<=m;i++){
            ll x,y,a,b;
            scanf("%lld%lld%lld%lld",&x,&y,&a,&b);
            add(x,y,a,b);
            add(y,x,a,b);
            u[i]=node(x,y,a,b);
        }
        pre_spfa();
        spfa(); 
    
        for(ll i=1;i<=n;i++)
            if(lst[i]==1&&dis[i]>1e9){
                puts("Impossible
    ");
                return 0;
            }
        for(ll i=1;i<=m;i++){
            ll x=u[i].x,y=u[i].y;
            if(lst[x]==-1&&dis[y]<u[i].l){
                puts("Impossible
    ");
                return 0;
            }
            if(lst[y]==-1&&dis[x]<u[i].l){
                puts("Impossible
    ");
                return 0;
            }
        }
    //    for(ll i=1;i<=n;i++)
    //        printf("lim=%lld dis=%lld
    ",lim[i],dis[i]);
        for(ll i=1;i<=m;i++){
            ll x=u[i].x,y=u[i].y;
            if(lst[x]==-1||lst[y]==-1) printf("%lld
    ",u[i].l);
            else printf("%lld
    ",max(dis[x],dis[y])>u[i].r?u[i].l:max(u[i].l,max(dis[x],dis[y])));
        }
    }
    View Code
  • 相关阅读:
    SpringBoot 部署 docker 打包镜像
    Android上dip、dp、px、sp等单位说明(转)
    mac下svn问题——“.a”(静态库)文件无法上传解决
    Mac OS X 访问 Windows 共享文件夹
    svn不能添加.a文件的解决方法
    UIView的剖析(转)
    mac 下真机调试 android 手机
    IOS-synthesize和dynamic的异同(转)
    IOS学习笔记之关键词@dynamic
    【转】APNs消息推送完整讲解
  • 原文地址:https://www.cnblogs.com/znsbc-13/p/11787412.html
Copyright © 2011-2022 走看看