【CF2B The least round way】题解
题目链接
题目
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.
给定由非负整数组成的 的正方形矩阵,你需要寻找一条路径:
以左上角为起点
每次只能向右或向下走
以右下角为终点
并且,如果我们把沿路遇到的数进行相乘,积应当是最小“round”,换句话说,应当以最小数目的0的结尾.
思路
要使0结尾最少,也就是要使以2结尾和以5结尾最少,因为0的个数并不是由多的那个因子觉定的,而是由少的那个因子觉定的,所以我们可以看一下从起点到终点2和5最少出现多少次,取个min值就是答案,这个过程可以用dp来实现。
要注意的是,如果出现0,那么必然存在一条道路只有1个0结尾,这时我们就要与前面那种情况作比较,有更优的输出。
总结
一开始做这道题时想的是要把其中一个因子(也就是2或5)的个数压到dp转态中(就是 表示在 号格子当5的个数为 时,2的个数最少为 ),类似一种dp的方法,这使我想不出怎么优化。
后来看题解,发现本质上0的个数是由2和5中较少那个数的数量觉定的,这个思路挺妙。其实对于这种题,尤其是背包累,当要存的转态多时,可以看看答案是否有小的那个数量觉定。
Code
#include<bits/stdc++.h>
using namespace std;
#define int long long
inline int read(){int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;
ch=getchar();}while(ch>='0'&&ch<='9'){x=(x<<1)+
(x<<3)+(ch^48);ch=getchar();}return x*f;}
//#define M
//#define mo
#define N 1010
int n, m, i, j, k;
int a[N][N], dp[N][N][2], f[N][N][2], ans;
void dfs(int x, int y, int k)
{
// printf("%d %d %d\n", x, y, k);
// if(x==1||y==1) return ;
// if(x==1&&y==1) return ;
if(f[x][y][k]==1) dfs(x, y-1, k), putchar('R');
if(f[x][y][k]==-1) dfs(x-1, y, k), putchar('D');
}
signed main()
{
// freopen("tiaoshi.in", "r", stdin);
// freopen("tiaoshi.out", "w", stdout);
memset(dp, 0x3f, sizeof(dp));
dp[0][1][0]=dp[0][1][1]=0;
ans=0x7fffffff;
n=read();
for(i=1; i<=n; ++i)
for(j=1; j<=n; ++j)
{
a[i][j]=read();
if(!a[i][j]) ans=1;
while(a[i][j]&&a[i][j]%2==0) a[i][j]/=2, ++m;
dp[i][j][0]=min(dp[i-1][j][0], dp[i][j-1][0])+m; m=0;
f[i][j][0]=(dp[i-1][j][0]<dp[i][j-1][0] ? -1 : 1);
while(a[i][j]&&a[i][j]%5==0) a[i][j]/=5, ++m;
dp[i][j][1]=min(dp[i-1][j][1], dp[i][j-1][1])+m; m=0;
f[i][j][1]=(dp[i-1][j][1]<dp[i][j-1][1] ? -1 : 1);
if(i==1&&j==1) f[i][j][0]=f[i][j][1]=0;
// printf("%lld %lld\n", dp[i][j][0], dp[i][j][1]);
}
printf("%lld\n", min(ans, min(dp[n][n][0], dp[n][n][1])));
if(ans<min(dp[n][n][0], dp[n][n][1]))
{
for(i=1; i<=n; ++i)
for(j=1; j<=n; ++j)
if(!a[i][j])
{
for(k=1; k<i; ++k) printf("D");
for(k=1; k<j; ++k) printf("R");
for(k=i; k<n; ++k) printf("D");
for(k=j; k<n; ++k) printf("R");
return 0;
}
}
if(dp[n][n][0]<dp[n][n][1]) dfs(n, n, 0);
else dfs(n, n, 1);
return 0;
}
本文来自博客园,作者:zhangtingxi,转载请注明原文链接:https://www.cnblogs.com/zhangtingxi/p/15720399.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!