zoukankan      html  css  js  c++  java
  • codeforces 597

    D题

    在一个二维平面上面,有n个城市,现在每个城市都没有电。

    你可以选择一些城市建发电站,代价是c[i];你也可以给每个城市拉电线,给城市(i,j)之间拉电线的代价是(abs(x[i]-x[j])+abs(y[i]-y[j]))*(k[i]+k[j])。

    现在问你最少花费多少代价,能够使得全部城市都有电,输出方案。

    题解

    建立一个超级源点,每个城市与超级源点连边,权重为第i个城市建设发电站的代价

    问题就转化为普通最小生成树问题

    prim kruskal都可以

    注意保留下路径

    与0节点相连的都是自建发电站

    #include<bits/stdc++.h>
    using namespace std;
    #define int long long
    #define sc(x) scanf("%I64d",&x);
    #define si signed
    #define fi first
    #define se second
    #define pb push_back
    #define forn for(int i=0;i<n;i++)
    int n;
    #define P pair<int,int>
    P A[2005];
    int C[2005];
    int K[2005];
    
    int d[2005];
    bool vis[2005];
    int mp[2005][2005];
    int pre[2005];
    vector<int>v;
    vector<P> vv;
    
    void prim()
    {
       // vis[0]=1;
        for(int i=1; i<=n; i++)
        {
            d[i]=1e18;
        }
        d[0]=0;
        for(int i=0; i<=n; i++)
        {
            int x=-1;
            for(int j=0; j<=n; j++)
                if(!vis[j]&&(x==-1||d[j]<d[x]))x=j;
            if(x==-1)break;
            vis[x]=1;
            for(int j=0; j<=n; j++)
            {
                if(!vis[j]){
                   if(d[j]>mp[x][j]){pre[j]=x;d[j]=mp[x][j];}
                }
            }
        }
    }
    si main()
    {
        sc(n)
        for(int i=1; i<=n; i++)
        {
            sc(A[i].fi)
            sc(A[i].se)
        }
        for(int i=1; i<=n; i++)
        {
            sc(C[i])
            mp[i][0]=mp[0][i]=C[i];
        }
        for(int i=1; i<=n; i++)sc(K[i]);
        for(int i=1; i<=n; i++)
        {
            for(int j=1; j<=n; j++)
            {
                mp[i][j]=(K[i]+K[j])*((labs(A[i].fi-A[j].fi))+(labs(A[i].se-A[j].se)));
            }
        }
        prim();
        int ans=0;
        for(int i=0; i<=n; i++)
        {
            ans+=d[i];
        }
        cout<<ans<<'
    ';
        memset(vis,0,sizeof vis);vis[0]=1;
        for(int i=1;i<=n;i++){
            if(pre[i]==0){
                v.push_back(i);
                vis[i]=1;
            }
        }
        cout<<v.size()<<endl;
        for(int i=0;i<v.size();i++)cout<<v[i]<<' ';
        cout<<endl;
        for(int i=1;i<=n;i++){
            if(!vis[i]){
                vv.push_back(P(i,pre[i]));
                vis[i]=1;
            }
        }
        cout<<vv.size()<<endl;
        for(int i=0;i<vv.size();i++)cout<<vv[i].fi<<' '<<vv[i].se<<endl;
    }
    

      C

    简单dp,字符串中他会把源字符串的w翻译成uu,把m变成nn,现在给你一个字符串问他的源字符串有多少种

    #include<bits/stdc++.h>
    using namespace std;
    #define int long long
    #define sc(x) scanf("%I64d",&x);
    #define si signed
    #define fi first
    #define se second
    #define pb push_back
    #define forn for(int i=0;i<n;i++)
    char s[100005];
    const int mod= 1e9+7;
    int dp[100005];
    void init()
    {
        dp[0]=dp[1]=1;
        for(int i=2;i<=100000;i++){
            dp[i]=(dp[i-1]+dp[i-2])%mod;
        }
    }
    si main()
    {
        init();
        scanf("%s",s+1);
        int n=strlen(s+1);
        int ans=1;
        for(int i=1;i<=n;){
            if(s[i]=='w'||s[i]=='m'){
                puts("0");
                return 0;
            }
            if(s[i]=='u'){
                int k=0;
                while(i<=n){
                    if(s[i]=='u')k++,i++;
                    else break;
                }
                ans=(ans*dp[k])%mod;
            }else if(s[i]=='n'){
                int k=0;
                while(i<=n){
                    if(s[i]=='n')k++,i++;
                    else break;
                }
                ans=(ans*dp[k])%mod;
            }else i++;
        }
        cout<<ans<<'
    ';
     
    }
    

      E

    期望dp

    现在有一个10*10的矩阵,玩家要从左下角走到左上角,会先往右边走,再往左边走,再往右边走(看NOTE里面的图),然后这个图里面有一些梯子,用梯子可以爬到上面去。

    现在这个人在掷骰子,问你期望最少花费多少次,能够到达终点。

    如果你到终点前,你的骰子超过了终点,那么将不会移动。

    首先dp【i】表示走到第i步的最小期望,由于在终点附件那里如果步数超过,那只能原地走

    dp【1】=1//6*(dp0+1)+5/6(dp1+1)

    dp【2】=1/6*(dp0+1)+1/6*(dp1+1)+2/3*(dp2+1)

    由于dp0=0;

    故dp1至dp5可求出来是6;

    接下来的每个点就是,先不考虑地图的梯子,先考虑转移

    就是dp【i】+=sigma(j=1~6)【(1/6)*d[i-j]】

    当有梯子时,直接考虑要不要用梯子就行,取min最小值

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn = 15;
    double dp[maxn*maxn];
    int idx[maxn][maxn];
    int ladders[maxn*maxn];
    int main(){
        for(int i=0;i<10;i++){
            for(int j=0;j<10;j++){
                if(i%2){
                    idx[i][j]=(i*10+9-j);
                }else{
                    idx[i][j]=(i*10+j);
                }
            }
        }
    //        for(int i=0;i<10;i++){
    //        for(int j=0;j<10;j++){
    //            cout<<idx[i][j]<<' ';
    //        }
    //        puts("");
    //        }
        for(int i=0;i<10;i++){
            for(int j=0;j<10;j++){
                int x;scanf("%d",&x);
                ladders[idx[i][j]]=idx[i-x][j];
            }
        }
        for(int i=0;i<10;i++){
            for(int j=0;j<10;j++){
                cout<<ladders[idx[i][j]]<<' ';
            }
            puts("");
        }
        dp[0]=0;
        for(int i=1;i<6;i++)
            dp[i]=6;
        for(int i=6;i<100;i++){
            double sum = 0;
            for(int step=1;step<=6;step++){
                sum = sum + min(dp[i-step],dp[ladders[i-step]]);
            }
            dp[i]=(sum/6)+1;
        }
        cout<< setprecision(10) << dp[99] << endl;
    }
    

      

  • 相关阅读:
    通过修改manifest文件来解决Vista/Win7/Win8/win10下应用程序兼容性问题
    windows下django开发环境配置
    Django网站实例效果
    手动下载Linux安装包perf
    【Nginx】负载配置
    【VIM】常用命令
    【CentOS7】SCP服务器间传文件
    【CentOS7】目录统计du命令
    【CentOS7】安装GraphicsMagick
    【Nginx】限流配置
  • 原文地址:https://www.cnblogs.com/hgangang/p/12326714.html
Copyright © 2011-2022 走看看