B.The least round way (dp)

题目链接

  http://codeforces.com/problemset/problem/2/B

这题对dp的理解要求高一些,运用到三维dp,存下每个点含有二的因子/五的因子的最小值,最后用string函数和reverse反转函数输出。这题还要特别注意矩阵中值为0的元素,0乘以任何数都得0.

#include <bits/stdc++.h>
using namespace std;
#define  MAXN 1005
#define  INF 0x7fffffff
int path[MAXN][MAXN][2];
int dp[MAXN][MAXN][2],a[MAXN][MAXN][2],n;
int zerox,zeroy,x;
string s;
bool flag;
int main()
{
    scanf("%d",&n);
    flag=false;
    for(int i=0;i<n;i++)
        for(int j=0;j<n;j++)
        {
            scanf("%d",&x);
            if(!x)
            {     
                a[i][j][0]=a[i][j][1]=1;
                zerox=i,zeroy=j,flag=true;
            }
            else
            {
                while(x%2==0) {a[i][j][0]++;x/=2;}
                while(x%5==0) {a[i][j][1]++,x/=5;}
            }
        }
        for(int k=0;k<2;k++)
            for(int i=0;i<n;i++)
                for(int j=0;j<n;j++)
                {
                    int ans=INF;
                    if(i==0&&j==0) ans=0;
                    if(i!=0&&dp[i-1][j][k]<ans) ans=dp[i-1][j][k];
                    if(j!=0&&dp[i][j-1][k]<ans) ans=dp[i][j-1][k],path[i][j][k]=1;
                    dp[i][j][k]=ans+a[i][j][k];
                }
                int k=dp[n-1][n-1][0]<dp[n-1][n-1][1]?0:1;
                if(flag&&dp[n-1][n-1][k]>1)
                {
                    for(int i=0;i<zeroy;i++)
                        s+="R";
                    for(int i=0;i<zerox;i++)
                        s+="D";
                    for(int i=0;i<n-zeroy-1;i++)
                        s+="R";
                    for(int i=0;i<n-zerox-1;i++)
                        s+="D";
                    cout<<1<<endl<<s<<endl;
                }
                else
                {
                    int i=n-1,j=n-1;
                    while(i>0||j>0)
                    {
                        if(path[i][j][k]==1)
                            s+="R",j--;
                        else
                            s+="D",i--;
                    }
                    reverse(s.begin(),s.end());
                    cout<<dp[n-1][n-1][k]<<endl<<s<<endl;
                }
                return 0;
}

猜你喜欢

转载自blog.csdn.net/intelligentgirl/article/details/81875334
way