NOIP2018提高组省一冲奖班模测训练(一)题解

http://www.51nod.com/contest/problemList.html#!contestId=72&randomCode=147206

原题水题大赛。。

A.珂朵莉的旅行

发现不管非叶子节点选什么,都可以改变叶子节点来满足条件,所以直接算即可

#include<bits/stdc++.h>
#define REP(i,a,b) for(int i(a);i<=(b);++i)
using namespace std;
typedef long long ll;
const int N=1e6+7,p=1e9+7;
int n,d[N];
inline int read(){char c;int w;
    while(!isdigit(c=getchar()));w=c&15;
    while(isdigit(c=getchar()))w=w*10+(c&15);return w;
}
int main(){
    n=read();
    REP(i,1,n-1){
        int x,y;x=read(),y=read();
        ++d[x];++d[y];
    }
    ll cnt=1,ans=0;
    REP(i,1,n)if(d[i]>1)(cnt<<=1)%=p;
    REP(i,1,n)if(d[i]==1)ans+=cnt<<1;else ans+=cnt;
    cout<<ans%p<<endl;
    return 0;
}

B.奈芙莲的序列

把原序列反过来做LIS

#include<bits/stdc++.h>
#define REP(i,a,b) for(int i(a);i<=(b);++i)
using namespace std;
typedef long long ll;
inline int read(){char c,p=0;int w;
    while(!isdigit(c=getchar()))if(c=='-')p=1;w=c&15;
    while(isdigit(c=getchar()))w=w*10+(c&15);return p?-w:w;
}
inline char smax(int&x,const int&y){return x<y?x=y,1:0;}
inline char smin(int&x,const int&y){return x>y?x=y,1:0;}
const int N=5e5+5;
int n,a[N],b[N],c[N],d[N];
int main(){
    n=read();
    REP(i,1,n)a[i]=b[i]=read();
    sort(b+1,b+1+n);int m=unique(b+1,b+1+n)-b-1;
    REP(i,1,n)c[n+i]=c[n-i+1]=lower_bound(b+1,b+1+m,a[i])-b;
    int len=1;d[1]=c[1];
    REP(i,2,n<<1){
        if(c[i]>d[len])d[++len]=c[i];else *lower_bound(d,d+len,c[i])=c[i];
    }
    cout<<len;
    return 0;
}

C.奈芙莲的护符

基础状压DP

#include<bits/stdc++.h>
#define REP(i,a,b) for(int i(a);i<=(b);++i)
using namespace std;
typedef long long ll;
inline char smax(int&x,const int&y){return x<y?x=y,1:0;}
inline char smin(int&x,const int&y){return x>y?x=y,1:0;}
int n,k,c[22][22],f[1<<21],g[22][1<<21],L[1<<21];
int main(){
    scanf("%d%d",&n,&k);if(n==k)return puts("0"),0;
    REP(i,1,n)REP(j,1,n)scanf("%d",&c[i][j]);
    REP(t,1,n)REP(i,1,n)REP(j,1,n)smin(c[i][j],c[i][t]+c[t][j]);
    const int st=(1<<n)-1;
    L[1]=0;
    REP(i,2,st)L[i]=L[i>>1]+1;
    memset(g,0x3f,sizeof g);
    REP(i,1,n){
        REP(s,1,st)if((s&(s-1))==0)g[i][s]=c[i][L[s&-s]+1];
        else g[i][s]=min(g[i][s&(s-1)],c[i][L[s&-s]+1]);    
    }
    memset(f,0x3f,sizeof f);
    int ans=f[0];f[0]=0;
    REP(s,0,st){
        int cnt=0;
        REP(i,1,n)if(s>>i-1&1^1)smin(f[s|(1<<i-1)],f[s]+g[i][st^s^(1<<i-1)]);
        
        else ++cnt;
        if(cnt==n-k)smin(ans,f[s]);
    }
    cout<<ans;
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/HolyK/p/9830183.html