CF 2B The least round way DP+Math

来源:互联网 发布:windows xp 下载 编辑:程序博客网 时间:2024/06/06 06:52
题意: 找出一条路, 使每个节点相乘,得到的数末尾 0 最少

每次移动只能向右或者向下, 找到后打印路径


///
按照题目要求,就是找出一条从左上角到右下角中每个数含2 or 5 最少的路///可以用Dp的思想, 然后把每个节点该走的方向记下来///再从终点回溯,把路径存入栈,再输出///数据会有0的情况, 这时候我们应该记录离终点最近的0#include<bits/stdc++.h>using namespace std;typedef long long LL;typedef unsigned long long ULL;const int maxn = 1000 + 7;LL Map[maxn][maxn];LL Dp[maxn][maxn][2];char Step[maxn][maxn][2];stack<char> Mesure;int Factor(int Num, int Base) ///得到因子 2 和 5 的个数{ if(Num == 0) return 1; int ret = 0; while(Num % Base == 0) { ret++; Num /= Base; } return ret;}int main(){ ios::sync_with_stdio(false); cin.tie(0); int n; cin >> n; bool Zero = false; int Zero_Pos; for(int i = 0; i < n; ++i) { for(int j = 0; j < n; ++j) { cin >> Map[i][j]; if(Map[i][j] == 0) { Zero = true; Zero_Pos = i; } Dp[i][j][0] = Factor(Map[i][j],2); Dp[i][j][1] = Factor(Map[i][j],5); } } for(int i = 0; i < n; ++i) { for(int j = 0; j < n; ++j) { for(int k = 0; k < 2; ++k) { if(i == 0 && j == 0) continue; if(i == 0) { Dp[i][j][k] += Dp[i][j-1][k]; Step[i][j][k] = 'R'; } else if(j == 0) { Dp[i][j][k] += Dp[i-1][j][k]; Step[i][j][k] = 'D'; } else { Dp[i][j][k] += min(Dp[i-1][j][k],Dp[i][j-1][k]); Step[i][j][k] = Dp[i-1][j][k] < Dp[i][j-1][k] ? 'D' : 'R'; } } } } if(min(Dp[n-1][n-1][0],Dp[n-1][n-1][1]) > 1 && Zero) { printf("1\n"); for(int i = 0; i < Zero_Pos; ++i) putchar('D'); for(int i = 0; i < n-1; ++i) putchar('R'); for(int i = Zero_Pos; i < n-1; ++i) putchar('D'); // } else { printf("%d\n",min(Dp[n-1][n-1][0],Dp[n-1][n-1][1])); int k = 0; k = Dp[n-1][n-1][0] < Dp[n-1][n-1][1] ? 0 : 1; for(int i = n-1, j = n-1; i != 0|| j != 0; ) { Mesure.push(Step[i][j][k]); if(Step[i][j][k] == 'D') i--; else j--; } while( !Mesure.empty() ) putchar(Mesure.top()), Mesure.pop(); } puts(""); return 0;}

 

0 0
原创粉丝点击