CodeForces B. The least round way(dp)
题目链接:http://codeforces.com/problemset/problem/2/B
There is a square matrix n × n, consisting of non-negative integer numbers. You should find such a way on it that
- starts 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.
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).
In the first line print the least number of trailing zeros. In the second line print the correspondent way itself.
3 1 2 3 4 5 6 7 8 9
0 DDRR
题意:
从左上到右下!
选出一条能让走过的路径的数字的积中含有最少的零!
PS:
积要含有零仅仅能是2 或者5形成。寻找一条含有2或者5 最少的路径就可以!
注意推断矩阵中是否有零的情况!
代码例如以下:
//http://blog.csdn.net/azheng51714/article/details/8240390 #include <cstdio> #include <cstring> const int maxn = 1017; int m[2][maxn][maxn]; int dp[2][maxn][maxn]; //dp[0][i][j]到i、j时有多少个2; //dp[1][i][j]到i、j时有多少个5。 int vis[2][maxn][maxn]; int n; int solve(int mark) { vis[mark][1][1] = 0; dp[mark][1][1] = m[mark][1][1]; for(int i = 1; i <= n; i++) { for(int j = 1; j <= n; j++) { if(i==1 && j==1) continue; if(i == 1) { dp[mark][i][j] = dp[mark][i][j-1] + m[mark][i][j]; vis[mark][i][j] = 1;//向右 } else if(j == 1) { dp[mark][i][j] = dp[mark][i-1][j] + m[mark][i][j]; vis[mark][i][j] = 0;//向下 } else { int tt1 = dp[mark][i-1][j]; int tt2 = dp[mark][i][j-1]; if(tt1 < tt2) { dp[mark][i][j] = tt1 + m[mark][i][j]; vis[mark][i][j] = 0; } else { dp[mark][i][j] = tt2 + m[mark][i][j]; vis[mark][i][j] = 1; } } } } return dp[mark][n][n]; } void print(int mark, int x, int y) { if(x==1 && y==1) return ; if(vis[mark][x][y] == 0) { print(mark,x-1,y); printf("D"); } else { print(mark,x,y-1); printf("R"); } } int main() { int x, y; while(~scanf("%d",&n)) { int tt, t1, t2; memset(vis,0,sizeof(vis)); memset(m,0,sizeof(m)); int flag = 0; for(int i = 1; i <= n; i++) { for(int j = 1; j <= n; j++) { scanf("%d",&tt); if(tt == 0) { flag = 1; x = i; y = j; continue; } t1 = t2 = tt; while(t1%2 == 0) { t1/=2; m[0][i][j]++; } while(t2%5 == 0) { t2/=5; m[1][i][j]++; } } } int ans1 = solve(0);//路径存在最少的2的个数 int ans2 = solve(1);//路径存在最少的5的个数 //printf("ans1:%d ans2:%d\n",ans1,ans2); int mark = 0; int ans = 0; if(ans1 < ans2) { ans = ans1; mark = 0; } else { ans = ans2; mark = 1; } if(flag && ans > 1) { printf("1\n");//有零存在那么终于结果就仅仅有一个零 for(int i = 2; i <= x; i++) { //向下到有零的那一行 printf("D"); } for(int j = 2; j <= n; j++) { //走到最右边 printf("R"); } for(int i = x+1; i <= n; i++) { //走到最下边 printf("D"); } printf("\n"); continue; } printf("%d\n",ans); print(mark, n, n); printf("\n"); } return 0; } /* 3 4 10 5 10 9 4 6 5 3 3 4 10 5 6 0 2 7 8 9 */
posted on 2017-07-15 14:43 yjbjingcha 阅读(221) 评论(0) 编辑 收藏 举报
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步