zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    spring boot 配置时区差别
    Java 中序列化与反序列化引发的思考?
    Http 状态码总结
    Springboot
    ConcurrentHashMap 实现缓存类
    C#基础(二)拆箱与装箱,循环与选择结构,枚举
    C#基础知识(一)自己总结的。。。
    贪吃蛇大作战双人版加强版完整代码加详细步骤,不懂问博主 啦啦啦。
    C#数组随机生成四个随机数
    C#添加背景音乐
  • 原文地址:https://www.cnblogs.com/tuscjaf/p/13874680.html
Copyright © 2011-2022 走看看