codeforces 2B.The least round way(数学&dp)
2018-01-16 17:21
537 查看
The least round way
Description
There is a square matrix n × n, consisting of non-negative integer numbers. You should find such a way on it thatstarts in the upper left cell of the matrix;
each following cell is to the right or down from the current cell;
the way ends in the bottom right cell.
Moreover, if we multiply together all the numbers along the way, the result should be the least “round”. In other words, it should end in the least possible number of zeros.
给定一个n*n的矩阵,找到一条从左上角到右下角的路线(只能往右/下走),使路过的数字乘积有最少后缀0
Input
The first line contains an integer number n (2 ≤ n ≤ 1000), n is the size of the matrix. Then follow n lines containing the matrix elements (non-negative integer numbers not exceeding 109).第一行输入n,然后输入矩阵
Output
In the first line print the least number of trailing zeros. In the second line print the correspondent way itself.第一行一个数字表示做少后缀0的数量,第二行输入路线(右和下分别用’R’和’D’表示)
Hint
我们通过数学知识知道,后缀0代表该数是10的倍数,应由若干2*5产生,我们把每个格子里的数因数分解预处理出它包含的2和5的数量,则用a[i][j][0]表示因子中2的数量,用a[i][j][1]表示因子中5的数量则问题转化为:从左上角到右下角找一条路径,使得路过的min(2,5)最小
则dp方程很好设计:dp[i][j][0/1]=min(dp[i−1][j][0/1],dp[i][j−1][0/1])+a[i][j][0/1]
其中dp[i][j][0]表示从左上角到(i,j)经过的最少2数,dp[i][j][1]表示从左上角到(i,j)经过的最少5数,还要用c数组记录路径(或者递归找路径)
! 注意:如果出现0,经过它的路径就会只有1个后缀0,但是可能找到没有后缀0的路径,所以我们先把0当成10
Code
#include <iostream> #include <cstring> #include <cstdio> #include <algorithm> #define MAX 1007 using namespace std; int n,x; int dp[2][MAX][MAX]; int p[2][MAX][MAX]; void print ( int x , int y , int k , int f ) { if ( x == 1 && y == 1 ); else if ( x == 1 ) print ( x , y-1 , k , 0); else if ( y == 1 ) print ( x-1 , y , k , 1); else { if ( dp[k][x][y] == dp[k][x-1][y] + p[k][x][y] ) print ( x-1 , y , k , 1 ); else print ( x , y-1 , k , 0); } if ( f == 3 ) return; printf ( "%c" , f?'D':'R' ); } int main ( ) { while ( ~scanf ( "%d" , &n ) ) { int flag = 0,a,b; for ( int i = 1 ; i <= n ; i++ ) for ( int j = 1 ; j <= n ; j++ ) { scanf ( "%d" , &x ); if ( !x ) { flag = 1; p[0][i][j]++; p[1][i][j]++; a = i , b = j; continue; } while ( x%2 == 0 ) { p[0][i][j]++; x /= 2; } while ( x%5 == 0 ) { p[1][i][j]++; x /= 5; } } memset ( dp , 0x3f , sizeof ( dp ) ); for ( int k = 0 ; k < 2 ; k++ ) for ( int i = 1 ; i <= n ; i++ ) for ( int j = 1 ; j <= n ; j++ ) { if ( i-1 ) dp[k][i][j] = min ( dp[k][i][j] , dp[k][i-1][j] ); if ( j-1 ) dp[k][i][j] = min ( dp[k][i][j] , dp[k][i][j-1] ); if ( i == j && i == 1 ) dp[k][i][j] = 0; dp[k][i][j] += p[k][i][j]; } int ans = min ( dp[0] , dp[1] ); if ( ans > 1 && flag ) { puts ( "1"< aec7 /span> ); for ( int i = 1 ; i < a ; i++ ) printf ( "%c" , 'D' ); for ( int j = 1 ; j < b ; j++ ) printf ( "%c" , 'R' ); for ( int i = a ; i < n ; i++ ) printf ( "%c" , 'D' ); for ( int j = b ; j < n ; j++ ) printf ( "%c" , 'R' ); puts ( "" ); continue; } printf ( "%d\n" , ans ); if ( dp[0] < dp[1] ) print ( n , n , 0 , 3 ); else print ( n , n , 1 , 3 ); puts ( "" ); } }
相关文章推荐
- codeforces 2B The least round way(DP+数学)
- CodeForces 2B The least round way(dp+数学)
- codeforces 2B The least round way DP因子路径
- 最小较小codeforces 2B The least round way
- Codeforces 2B. The least round way(动态规划)
- codeforces 2B The least round way
- Codeforces 2B. The least round way
- 【Codeforces Beta Round 2B】【贪心 DP】The least round way 从(1,1)走到(n,n)乘积尾数0尽可能少
- CodeForces 2B The least round way
- [codeforces] 2B - The least round way
- codeforces 2B The least round way
- codeforces 2B The least round way
- CF 2B The least round way(DP)
- Codeforces 2B: The least round way【动态规划】
- Codeforces 2B The least round way
- Codeforces 2B The least round way
- Codeforces2B - The least round way(DP)
- CF 2B.The least round way
- CodeForces B. The least round way(dp)
- CF 2B The least round way