• codeforces 2B The least round way 【DP】


     VJ上可找到中文题意。

    思路:

    首先分解有多少2与多少5.接下来就是dp。

    分两次,一次是根据2的数量贪心,另外一次是根据5的数量贪心,看哪一次乘积的末尾0最少。

    需要注意的是两点:

    1.输入有0的情况,要判断你的ans是不是大于1如果大于1那么输出一条经过0的路径即可。

    2.当根据2的数量贪心进行dp的时候,如果可以转移的两个来源的2的数量是相同的,需要找到5的数量较小的状态转移过来。

    代码较挫。

    #include<bits/stdc++.h>
    using namespace std;
    int er[1005][1005],wu[1005][1005];
    int dp[1005][1005],dpp[1005][1005];
    bool from1[1005][1005],from2[1005][1005];
    void print(bool p[][1005],int n){
        stack<int>s;
        int x=n-1,y=n-1;
        while(x!=0||y!=0){
            s.push(p[x][y]);
            if(p[x][y]==0)y--;
            else x--;
        }
        while(!s.empty()){
            int tmp=s.top();
            s.pop();
            if(tmp)printf("D");
            else printf("R");
        }
    }
    int main()
    {
        int n;
        scanf("%d",&n);
        bool ok=0;
        int x,y;
        for(int i=0;i<n;i++){
            for(int j=0;j<n;j++){
                int tmp;
                scanf("%d",&tmp);
                if(tmp==0){
                    ok=1;
                    x=i;y=j;
                    continue;
                }
                while(tmp%2==0){
                    tmp/=2;
                    er[i][j]++;
                }
                while(tmp%5==0){
                    tmp/=5;
                    wu[i][j]++;
                }
            }
        }
        for(int i=0;i<n;i++){
            for(int j=0;j<n;j++){
                if(i==0){
                    if(j!=0){
                        dp[i][j]=dp[i][j-1]+er[i][j];
                        dpp[i][j]=dpp[i][j-1]+wu[i][j];
                        from1[i][j]=0;
                    }
                    else{
                        dp[i][j]=er[i][j];
                        dpp[i][j]=wu[i][j];
                    }
                }
                else{
                    if(j!=0){
                        if(dp[i-1][j]<dp[i][j-1]){
                            dp[i][j]=dp[i-1][j]+er[i][j];
                            dpp[i][j]=dpp[i-1][j]+wu[i][j];
                            from1[i][j]=1;
                        }
                        else if(dp[i-1][j]==dp[i][j-1]){
                            if(dpp[i-1][j]<dpp[i][j-1]){
                                dp[i][j]=dp[i-1][j]+er[i][j];
                                dpp[i][j]=dpp[i-1][j]+wu[i][j];
                                from1[i][j]=1;
                            }
                            else{
                                dp[i][j]=dp[i][j-1]+er[i][j];
                                dpp[i][j]=dpp[i][j-1]+wu[i][j];
                                from1[i][j]=0;
                            }
                        }
                        else{
                            dp[i][j]=dp[i][j-1]+er[i][j];
                            dpp[i][j]=dpp[i][j-1]+wu[i][j];
                            from1[i][j]=0;
                        }
                    }
                    else{
                        dp[i][j]=dp[i-1][j]+er[i][j];
                        dpp[i][j]=dpp[i-1][j]+wu[i][j];
                        from1[i][j]=1;
                    }
                }
            }
        }
        int ans=min(dp[n-1][n-1],dpp[n-1][n-1]);
        memset(dp,0,sizeof(dp));
        memset(dpp,0,sizeof(dpp));
        for(int i=0;i<n;i++){
            for(int j=0;j<n;j++){
                if(i==0){
                    if(j!=0){
                        dp[i][j]=dp[i][j-1]+wu[i][j];
                        dpp[i][j]=dpp[i][j-1]+er[i][j];
                        from2[i][j]=0;
                    }
                    else{
                        dp[i][j]=wu[i][j];
                        dpp[i][j]=er[i][j];
                    }
                }
                else{
                    if(j!=0){
                        if(dp[i-1][j]<dp[i][j-1]){
                            dp[i][j]=dp[i-1][j]+wu[i][j];
                            dpp[i][j]=dpp[i-1][j]+er[i][j];
                            from2[i][j]=1;
                        }
                        else if(dp[i-1][j]==dp[i][j-1]){
                            if(dpp[i-1][j]<dpp[i][j-1]){
                                dp[i][j]=dp[i-1][j]+wu[i][j];
                                dpp[i][j]=dpp[i-1][j]+er[i][j];
                                from2[i][j]=1;
                            }
                            else{
                                dp[i][j]=dp[i][j-1]+wu[i][j];
                                dpp[i][j]=dpp[i][j-1]+er[i][j];
                                from2[i][j]=0;
                            }
                        }
                        else{
                            dp[i][j]=dp[i][j-1]+wu[i][j];
                            dpp[i][j]=dpp[i][j-1]+er[i][j];
                            from2[i][j]=0;
                        }
                    }
                    else{
                        dp[i][j]=dp[i-1][j]+wu[i][j];
                        dpp[i][j]=dpp[i-1][j]+er[i][j];
                        from2[i][j]=1;
                    }
                }
            }
        }
        if(ans>min(dp[n-1][n-1],dpp[n-1][n-1])){
            ans=min(dp[n-1][n-1],dpp[n-1][n-1]);
            if(ans>1&&ok){
                puts("1");
                for(int i=0;i<x;i++){
                    printf("D");
                }
                for(int j=0;j<n-1;j++){
                    printf("R");
                }
                for(int i=x;i<n-1;i++){
                    printf("D");
                }
                return 0;
            }
            printf("%d
    ",min(dp[n-1][n-1],dpp[n-1][n-1]));
            print(from2,n);
        }
        else{
            if(ans>1&&ok){
                puts("1");
                for(int i=0;i<x;i++){
                    printf("D");
                }
                for(int j=0;j<n-1;j++){
                    printf("R");
                }
                for(int i=x;i<n-1;i++){
                    printf("D");
                }
                return 0;
            }
            printf("%d
    ",ans);
            print(from1,n);
        }
    }
  • 相关阅读:
    iOS开发>学无止境
    iOS开发>学无止境
    Review1(C#语言基础)
    Lua
    c#笔记(四)——switch
    鼠标拖拽物体
    lua-路径加载lua文件-函数返回值,访问lua文件中的变量
    lua-1-c# 执行lua文件-调用lua文件中的方法
    Unity实现手机录音功能
    lua-table类的继承
  • 原文地址:https://www.cnblogs.com/tun117/p/5401457.html
Copyright © 2020-2023  润新知