题目:The least round way

1000*1000的方阵,每个格子有一个非负整数,现在要从左上走到右下,每次只能向下或者向右走。目标是使得所有走的格子里的数的乘积里,末尾0的个数最少,要求输出最有解和走法。

不用怎么想也知道基本是个dp了,可以发现其实只有2和5的因子是有用的,但是如果状态同时记录2和5的因子个数的话,就不好表示了。其实方法很简单,对2个5分别做一次,第一次让2尽量少,第二次让5尽量少,两个里面取个最小的就是答案了,应该不难证明。dp过程就比较普通了,记录下路径,最后输出即可,不再赘述。

当然,本题是有一个比较大的trick的,就是如果其中有一个数字为0,那么最后的乘积可以为0,也就是答案至少可以是1。因此,只要先记录下方阵中有没有0,然后dp的时候强制不走0,最后输出走0和不走0的最优解即可。

#include <cstdio>
#include <algorithm>
using namespace std;
const int MAXN = 1024;
int m2[MAXN][MAXN];
int m5[MAXN][MAXN];
int l2[MAXN][MAXN];
int l5[MAXN][MAXN];
int dp2[MAXN][MAXN];
int dp5[MAXN][MAXN];
int n;
int zx, zy;
void output(int ll[MAXN][MAXN], int x, int y)
{
if (x == 0 && y == 0)
return;
if (ll[x][y] == 0)
{
output(ll, x - 1, y);
putchar('D');
}
else
{
output(ll, x, y - 1);
putchar('R');
}
}
int main()
{
scanf("%d", &n);
zx = zy = -1;
for (int i = 0; i < n; ++i)
{
for (int j = 0; j < n; ++j)
{
scanf("%d", &m2[i][j]);
if (m2[i][j] != 0)
{
m5[i][j] = 0;
while (m2[i][j] % 5 == 0)
{
++m5[i][j];
m2[i][j] /= 5;
}
int t = 0;
while (m2[i][j] % 2 == 0)
{
++t;
m2[i][j] /= 2;
}
m2[i][j] = t;
}
else
{
zx = i;
zy = j;
m2[i][j] = m5[i][j] = -1;
}
}
}
for (int i = 0; i < n; ++i)
{
for (int j = 0; j < n; ++j)
{
if (m2[i][j] == -1)
dp2[i][j] = -1;
else
{
if (i == 0 && j == 0)
dp2[i][j] = m2[i][j];
else
{
dp2[i][j] = 100000000;
if (i > 0 && dp2[i - 1][j] != -1 && dp2[i - 1][j] + m2[i][j] < dp2[i][j])
{
dp2[i][j] = dp2[i - 1][j] + m2[i][j];
l2[i][j] = 0;
}
if (j > 0 && dp2[i][j - 1] != -1 && dp2[i][j - 1] + m2[i][j] < dp2[i][j])
{
dp2[i][j] = dp2[i][j - 1] + m2[i][j];
l2[i][j] = 1;
}
if (dp2[i][j] == 100000000)
dp2[i][j] = -1;
}
}
}
}
for (int i = 0; i < n; ++i)
{
for (int j = 0; j < n; ++j)
{
if (m5[i][j] == -1)
dp5[i][j] = -1;
else
{
if (i == 0 && j == 0)
dp5[i][j] = m5[i][j];
else
{
dp5[i][j] = 100000000;
if (i > 0 && dp5[i - 1][j] != -1 && dp5[i - 1][j] + m5[i][j] < dp5[i][j])
{
dp5[i][j] = dp5[i - 1][j] + m5[i][j];
l5[i][j] = 0;
}
if (j > 0 && dp5[i][j - 1] != -1 && dp5[i][j - 1] + m5[i][j] < dp5[i][j])
{
dp5[i][j] = dp5[i][j - 1] + m5[i][j];
l5[i][j] = 1;
}
if (dp5[i][j] == 100000000)
dp5[i][j] = -1;
}
}
}
}
if (dp2[n - 1][n - 1] == -1)
{
printf("1\n");
for (int i = 0; i < n - 1; ++i)
putchar('D');
for (int i = 0; i < n - 1; ++i)
putchar('R');
puts("");
}
else
{
int now = min(dp2[n - 1][n - 1], dp5[n - 1][n - 1]);
if (zx != -1 && now >= 1)
{
printf("1\n");
for (int i = 0; i < zx; ++i)
putchar('D');
for (int i = 0; i < n - 1; ++i)
putchar('R');
for (int i = zx; i < n - 1; ++i)
putchar('D');
puts("");
}
else
{
printf("%d\n", now);
if (dp2[n - 1][n - 1] < dp5[n - 1][n - 1])
output(l2, n - 1, n - 1);
else
output(l5, n - 1, n - 1);
puts("");
}
}
return 0;
}

Codeforces Beta Round #2--B题 (DP)相关推荐

  1. Codeforces Beta Round #17 C. Balance DP

    C. Balance 题目链接 http://codeforces.com/contest/17/problem/C 题面 Nick likes strings very much, he likes ...

  2. Codeforces Beta Round #51 D. Beautiful numbers 数位dp + 状态优化

    传送门 文章目录 题意: 思路: 题意: 思路: 数位dpdpdp挺经典的一个题辣,有一个很明显的状态就是f[pos][num][lcm]f[pos][num][lcm]f[pos][num][lcm ...

  3. Codeforces Beta Round #5 B. Center Alignment 模拟题

    B. Center Alignment 题目连接: http://www.codeforces.com/contest/5/problem/B Description Almost every tex ...

  4. Codeforces Beta Round #4 (Div. 2 Only)

    Codeforces Beta Round #4 (Div. 2 Only) A 水题 1 #include<bits/stdc++.h> 2 using namespace std; 3 ...

  5. Codeforces Beta Round #7

    Codeforces Beta Round #7 http://codeforces.com/contest/7 A 水题 1 #include<bits/stdc++.h> 2 usin ...

  6. Codeforces Beta Round #17 D. Notepad (数论 + 广义欧拉定理降幂)

    Codeforces Beta Round #17 题目链接:点击我打开题目链接 大概题意: 给你 \(b\),\(n\),\(c\). 让你求:\((b)^{n-1}*(b-1)\%c\). \(2 ...

  7. Codeforces Beta Round #75 (Div. 1 Only) B. Queue 线段树。单点更新

    http://codeforces.com/problemset/problem/91/B 题意: 给你n个数,求得i 到n中小于a[i]的最右边的a[j],然后求a[i]到a[j]之间包含了多少个数 ...

  8. Codeforces Beta Round #22 (Div. 2 Only) E. Scheme(DFS+强连通)

    题目大意 给了 n(2<=n<=105) 个点,从每个点 u 出发连向了一个点 v(共 n 条边) 现在要求添加最少的边使得整个图是一个强连通图 做法分析 这道题千万不要一般化:先求强连通 ...

  9. codeforces beta round 1

    codeforces beta round 1 A Theatre Square in the capital city of Berland has a rectangular shape with ...

最新文章

  1. SDRAM 相关资料
  2. JS 星号 * 处理手机号和名称
  3. OncePerRequestFilter的作用
  4. 世界读书日,给你们送大福利!
  5. 服务器的安全措施有哪些呢?
  6. matlab simulink单相桥式逆变电路
  7. Linux----常用操作
  8. 大气污染治理行业有哪些特点?
  9. We Are A Team
  10. Android-再次解读萤石云视频
  11. java一系列图片加载_RxJava系列文章(一) - 网络图片加载水印一般写法
  12. VMware安装Ubuntu-18.04.3 Server版本
  13. rtthread 线程
  14. 一、万维网的发展(W3C组织的建立)
  15. CentOS Linux release 7.4.1708 (Core)操作系统安全加固
  16. 代码扫描 | 把控代码质量的利器
  17. PMBOK泛读(第十一章) - 项目风险管理
  18. 流水线性能吞吐率、加速比、效率计算
  19. linux shell获取当前执行路径
  20. [附源码]SSM计算机毕业设计网上学车预约系统JAVA

热门文章

  1. java imap 标记已读,JavaMail通过IMAP和POP3接收未读以及设置已读邮件
  2. oracle exp 二进制,Oracle备份之exp自动逻辑备份(二)
  3. Spring Security OAuth2源码解析(二)
  4. 天津市职高高一计算机试题及答案,职高(中职)数学(基础模块)上册题库.doc
  5. postman cookie设置_是时候抛弃Postman了,因为REST Client更香
  6. 一维数组名与二维数组名的关联
  7. 2019-05-21 Java学习日记之String类型Demo
  8. 三剑客之sed常用操作
  9. jquery模糊查询
  10. 【原创】网络报文抓取研究