codeforces 2B 动态规划
2016-05-16 13:37
417 查看
B. The least round way
time limit per test
5 seconds
memory limit per test
64 megabytes
input
standard input
output
standard output
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.
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).
Output
In the first line print the least number of trailing zeros. In the second line print the correspondent way itself.
Examples
input
output
题意:
从左上角到右下角, 每次只能往右或者往下走, 求所经过的路径中所有数相乘得到的结果末尾0最少的个数是多少, 并且吧路径输出.
分析:
求末尾的0的个数, 肯定是与原先的数中2的个数和5的个数有关, 我们先把原先的数中2的个数和5的个数记录下来, 然后两次dp,分别求出从左上角到右下角2的个数的最小值和5的个数的最小值; 两者取最小值就是答案, 同时在dp的过程中记录路径. 然后有一点需要注意的是有0的情况我们要特判, 先把0当成10来处理, 跑两遍dp, 如果最后的结果是0, 说明可以不经过0这条路径, 如果结果大于等于1, 那么只需要把0这条路径输出就行了.
time limit per test
5 seconds
memory limit per test
64 megabytes
input
standard input
output
standard output
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.
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).
Output
In the first line print the least number of trailing zeros. In the second line print the correspondent way itself.
Examples
input
3 1 2 3 4 5 6 7 8 9
output
0 DDRR
题意:
从左上角到右下角, 每次只能往右或者往下走, 求所经过的路径中所有数相乘得到的结果末尾0最少的个数是多少, 并且吧路径输出.
分析:
求末尾的0的个数, 肯定是与原先的数中2的个数和5的个数有关, 我们先把原先的数中2的个数和5的个数记录下来, 然后两次dp,分别求出从左上角到右下角2的个数的最小值和5的个数的最小值; 两者取最小值就是答案, 同时在dp的过程中记录路径. 然后有一点需要注意的是有0的情况我们要特判, 先把0当成10来处理, 跑两遍dp, 如果最后的结果是0, 说明可以不经过0这条路径, 如果结果大于等于1, 那么只需要把0这条路径输出就行了.
#include<bits/stdc++.h> #define inf 0x3f3f3f3f using namespace std; typedef long long ll; typedef pair<int,int> pii; const int N=1010,MOD=1e9+7; int a ; int dp ; int path [2],two ,five ; int main() { int n; scanf("%d",&n); int zero=0,x1,y1; for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ int cnt=0; scanf("%d",&a[i][j]); int t=a[i][j]; if(t==0){ t=10,zero=1; //把0当成10来处理 x1=i,y1=j; } while(t%2==0) t>>=1,cnt++; two[i][j]=cnt; cnt=0; while(t%5==0) t/=5,cnt++; five[i][j]=cnt; } } //边界特殊处理 for(int i=1;i<=n;i++) two[1][i] += two[1][i-1],five[1][i] += five[1][i-1]; for(int i=1;i<=n;i++) two[i][1] += two[i-1][1],five[i][1] += five[i-1][1]; for(int i=1;i<=n;i++) path[i][1][0] = path[i][1][1] = 1,path[1][i][0] = path[1][i][1] = 2; for(int i=2;i<=n;i++){ for(int j=2;j<=n;j++){ int t1 = two[i][j],t2=five[i][j]; if(i-1) { two[i][j] = two[i-1][j] + t1; path[i][j][0] = 1; //up } if(j-1 && two[i][j] > two[i][j-1] + t1) { two[i][j] = two[i][j-1] + t1; path[i][j][0] = 2; //right } if(i-1) { five[i][j] = five[i-1][j] + t2; path[i][j][1] = 1; //up } if(j-1 && five[i][j] > five[i][j-1] + t2) { five[i][j] = five[i][j-1] + t2; path[i][j][1] = 2; //right } } } int f=0; if(two >= five ) f=1; int ret = min(two ,five ); if(zero && ret>=1){ //选择经过0的路径 puts("1"); int t1=n-x1,t2=n-y1; x1--,y1--; while(y1--) putchar('R'); while(x1--) putchar('D'); while(t1--) putchar('D'); while(t2--) putchar('R'); return 0; } // cout<<"f=="<<f<<endl; // for(int i=1;i<=n;i++){ // for(int j=1;j<=n;j++){ // printf("%d ",path[i][j][f]); // } // puts(""); // } printf("%d\n",ret); int x=n,y=n; vector<char> ans; while(x!=1 || y!=1) { if(path[x][y][f] == 1) ans.push_back('D'),x--; else ans.push_back('R'),y--; } reverse(ans.begin(),ans.end()); for(int i=0;i<ans.size();i++){ putchar(ans[i]); } return 0; }
相关文章推荐
- 将EditText光标放在文章末尾
- Jquery 可见性过滤器选择器
- Python菜鸟之路:Python基础(二)
- 数据库抽象层PDO
- J2EE企业级定时调度
- leetcode minimum window subString
- js深拷贝和浅拷贝
- 程序猿都该知道的MySQL秘籍
- zzulioj1783简单的求和
- AFN 与 ASI 有什么区别
- category使用 objc_setAssociatedObject/objc_getAssociatedObject 实现添加属性
- Spark性能优化第七季之Spark 钨丝计划
- 什么是linux下的checkpoint/restore
- 开博记录
- Oracle 软件及静默安装数据库
- DNS域名服务及搭建缓存DNS服务器详解(2)
- java 中的动态代理
- django访问sqlserver2000——使用django-pyodbc
- windows平台下Tuxedo应用simpapp编译失败问题解析
- 什么是Java反射