清北刷题冲刺 11-03 p.m

三向城

#include<iostream>
#include<cstdio>
using namespace std;
int n,x,y;
int main(){
    freopen("city.in","r",stdin);freopen("city.out","w",stdout);
//    freopen("Cola.txt","r",stdin);
    scanf("%d",&n);
    while(n--){
        scanf("%d%d",&x,&y);
        int ans=0;
        while(x!=y){
            ans++;
            if(x<y)swap(x,y);
            x/=2;
        }
        printf("%d
",ans);
    }
    return 0;
}
100分 两个同时往上跳

灵魂画师

#include<iostream> 
#include<cstdio>
#include<cstring>
using namespace std;
int n,c,K,mc,cnt[101];
double dp[101][101],ans;
int main(){
    freopen("paint.in","r",stdin);freopen("paint.out","w",stdout);
    scanf("%d%d%d",&n,&c,&K);
    for(int i=1;i<=K;i++){
        int l,r;
        scanf("%d%d",&l,&r);
        for(int j=l;j<=r;j++){
            cnt[j]++;
            mc=max(cnt[j],mc);
        }
    }
    dp[0][1]=1;
    for(int i=0;i<mc;i++){
        for(int j=0;j<c;j++){
            dp[i+1][j]+=dp[i][j]/2;
            for(int k=0;k<c;k++){
                dp[i+1][(j*k)%c]+=dp[i][j]/(2*c);
            }
        }
    }
    for(int i=1;i<=n;i++){
        for(int j=0;j<c;j++){
            ans+=dp[cnt[i]][j]*j;//概率乘以收益
        }
    }
    printf("%.3lf
",ans);
    return 0;
}
100分 概率dp

香子兰

#include<iostream>
#include<cstdio>
#define maxn 21
using namespace std;
int map[21][21],n,m,sum,num,head[maxn],fa[maxn],mx,mn=0x7fffffff;
bool flag=1;
struct node{
    int to,pre,v;
}e[maxn*maxn*2];
void Insert(int from,int to,int v){
    e[++num].to=to;
    e[num].v=v;
    e[num].pre=head[from];
    head[from]=num;
}
void dfs(int now,int father){
    bool leaf=0;
    fa[now]=father;
    for(int i=head[now];i;i=e[i].pre){
        int to=e[i].to;
        if(to==father)continue;
        dfs(to,now);
        leaf=1;
    }
    if(now==n&&leaf==0){
        flag=1;
        return;
    }
}
int main(){
    freopen("vanilla.in","r",stdin);freopen("vanilla.out","w",stdout);
//    freopen("Cola.txt","r",stdin);
    scanf("%d%d",&n,&m);
    int x,y,z;
    for(int i=1;i<=m;i++){
        scanf("%d%d%d",&x,&y,&z);
        mx=max(mx,z);mn=min(mn,z);
        x+=1;y+=1;
        map[x][y]=map[y][x]=z;
        Insert(x,y,z);Insert(y,x,z);
        sum+=z;
        if(x!=i||y!=i+1)flag=0;
    }
    if(flag){
        sum*=4;
        sum-=map[n][n-1]*2+map[1][2]*2;
        cout<<sum;
        return 0;
    }
    if(m==n-1){
        flag=0;
        dfs(1,0);
        if(flag){
            cout<<sum*4-map[n][fa[n]]*2;
        }
        else cout<<sum*4;
        return 0;
    }
    while(sum<177)sum*=2;
    sum%=177;
    if(sum<mx)sum+=mx*2;
    cout<<sum;
    return 0;
}
30分 乱搞骗分
#include<iostream>
#include<cstdio>
#define INF 1000000007
using namespace std;
int a[24][24],d[24][24],f[2][24][1050000],e[24];
int cnt[1050000],n,n1,n2,x,y,z,m,q,ans,sta;
int main(){
    freopen("vanilla7.in","r",stdin);
    e[0]=1;
    for(int i=1;i<=22;i++)e[i]=e[i-1]<<1;//预处理2^i
    for(int i=0;i<e[20];i++){
        int x=i;
        while(x){
            cnt[i]+=x&1;
            x>>=1;
        }
    }
    scanf("%d%d",&n,&m);
    int x,y,z;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++){
            if(i==j)continue;
            d[i][j]=INF;
        }
    for(int i=1;i<=m;i++){
        scanf("%d%d%d",&x,&y,&z);
        x++;y++;
        if(z>=d[x][y])continue;
        d[x][y]=d[y][x]=z;
    }
    for(int k=1;k<=n;k++)
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++){
                d[i][j]=min(d[i][j],d[i][k]+d[k][j]);
            }
    if(n==3){
        printf("%d
",(d[1][2]+d[2][3])*2);
        return 0;
    }
    n1=(n-2)/2;
    n2=n-2-n1;
    for(int q=0;q<=1;q++){
        for(int i=1;i<=n;i++)
            for(int j=0;j<e[n-2];j++)
            f[q][i][j]=INF;
        if(q==0)
            for(int i=2;i<n;i++)f[q][i][e[i-2]]=d[1][i];
        else
            for(int i=2;i<n;i++)f[q][i][e[i-2]]=d[n][i];
        for(int j=1;j<e[n-2];j++){
            if(cnt[j]<n2)
            for(int i=2;i<n;i++){
                if(f[q][i][j]<INF)
                for(int k=2;k<n;k++){
                    if(f[q][i][j]+d[i][k]<f[q][k][j|e[k-2]])
                    f[q][k][j|e[k-2]]=f[q][i][j]+d[i][k];        
                }
            }
        }
    }
    
    ans=INF;
    for(int sta=0;sta<e[n-2];sta++){
        if(cnt[sta]==n1){
            x=INF;
            for(int i=2;i<n;i++){
                if(sta&e[i-2])
                for(int j=2;j<n;j++){
                    if(!(sta&e[j-2])){
                        if(f[0][i][sta]+d[i][j]+f[1][j][e[n-2]-1-sta]<x)
                            x=f[0][i][sta]+d[i][j]+f[1][j][e[n-2]-1-sta];
                    }
                }
            }
            for(int i=2;i<n;i++){
                if(sta&e[i-2])
                for(int j=2;j<n;j++){
                    if(!(sta&e[j-2]))
                    if(x+f[1][i][sta]+d[i][j]+f[0][j][e[n-2]-1-sta]<ans)
                    ans=x+f[1][i][sta]+d[i][j]+f[0][j][e[n-2]-1-sta];
                }
            }
        }
    }
    printf("%d
",ans);
    return 0;
}
100分 floyed+状压dp
预计得分100+100+0
实际得分100+50+30
T1很简单,T2是个简单的概率dp,但是数组开小了,T3一点思路都没有,就研究了一下链和树的情况,乱搞了一下
数组开小很不应该们,不能再犯
小结
原文地址:https://www.cnblogs.com/thmyl/p/7779192.html