CF2B The least round way TJ

题目链接

思路

一眼看出考虑用动态规划。
分析,末尾 (0) 的个数与因数 (2,5) 的个数有关,那么我们输入的数组直接分别预处理成 (2) 的个数与 (5) 的个数就可以了。
其次,我们 (2,5) 的状态分别转移,取最终的最小值(因为如果没有 (5) ,取更多的 (2) 也没用)。
存储路径然后输出,也可以根据值的判断输出路径。

代码

需要控制的地方挺多,细心

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <utility>
using namespace std;
const int MAXN = 1e3 + 10;
struct node {
	int s_2 ,s_5;
	node () {
		s_2 = s_5 = 0x3f3f3f3f;
	}
}dp[MAXN][MAXN];
int path[2][MAXN][MAXN];
int n;
pair <int ,int > g[MAXN][MAXN];
void f (int x ,int r1 ,int r2) {
	int sum = 0 ,sum_ = 0;
	while (x % 2 == 0)
		x /= 2 ,sum ++;
	while (x % 5 == 0)
		x /= 5 ,sum_ ++;
	g[r1][r2].first = sum ,g[r1][r2].second = sum_;
}
void print (int x ,int y ,int cmp ,char dir) {
	if (x == 1 && y == 1) {
		printf ("%c",dir);
		return ;
	}
	if (path[cmp][x][y] == 0) print (x - 1 ,y ,cmp ,'D');
	else print (x ,y - 1 ,cmp ,'R');
	printf ("%c",dir);
}
int main () {
	scanf ("%d",&n);
	int x ,xx ,yy;
	bool has_0 = false;
	for (int q = 1;q <= n;++ q) {
		for (int w = 1;w <= n;++ w) {
			scanf ("%d",&x);
			if (x == 0) {
				has_0 = true ,xx = q ,yy = w;
				g[q][w] = make_pair (0 ,0);
				continue ;
			}
			f (x ,q ,w);
		}
	}
	dp[1][0].s_2 = dp[0][1].s_2 = 0 ,dp[1][0].s_5 = dp[0][1].s_5 = 0;
	for (int q = 1;q <= n;++ q) {
		for (int w = 1;w <= n;++ w) {
			if (dp[q - 1][w].s_2 < dp[q][w - 1].s_2)
				dp[q][w].s_2 = dp[q - 1][w].s_2 + g[q][w].first ,path[0][q][w] = 0;
			else dp[q][w].s_2 = dp[q][w - 1].s_2 + g[q][w].first ,path[0][q][w] = 1;
			if (dp[q - 1][w].s_5 < dp[q][w - 1].s_5)
				dp[q][w].s_5 = dp[q - 1][w].s_5 + g[q][w].second ,path[1][q][w] = 0;
			else dp[q][w].s_5 = dp[q][w - 1].s_5 + g[q][w].second ,path[1][q][w] = 1;
		}
	}
	if (has_0 && dp[n][n].s_2 > 1 && dp[n][n].s_5 > 1) {
		printf ("1
");
		for (int q = 1;q < xx;++ q) {
			printf ("D");
		}
		for (int q = 1;q < n;++ q) {
			printf ("R");
		}
		for (int q = xx;q < n;++ q) {
			printf ("D");
		}
		return 0;
	}
	printf ("%d
",min (dp[n][n].s_2 ,dp[n][n].s_5));
	if (dp[n][n].s_2 < dp[n][n].s_5) {
		(path[0][n][n] ? print (n ,n - 1 ,0 ,'R') : print (n - 1 ,n ,0 ,'D'));
	}
	else {
		(path[1][n][n] ? print (n ,n - 1 ,1 ,'R') : print (n - 1 ,n ,1 ,'D'));
	}
	return 0;
}

cb
原文地址:https://www.cnblogs.com/tuscjaf/p/13874680.html