• 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
  • 相关阅读:
    Vue生命周期
    事件
    改变this指向
    全屏要素
    微信小程序
    编程心得
    设计模式-单例与实例化
    第五节课 课堂总结
    作业四 分支结构
    课堂总结
  • 原文地址:https://www.cnblogs.com/tuscjaf/p/13874680.html
Copyright © 2020-2023  润新知