Codeforces #2B The least round way(DP)
Description
有一个n*n的正整数矩阵,要你求一条从第一行第一列的格子到第n行第n列的路,使得你走过的格子里面的数乘起来的值末尾的零的个数最小。输出最小个数。
Input
第一行包括1个数n。
接下来n行每行n个数字。
Output
一个数字表示末尾零最小个数。
Sample Input
3
1 2 3
4 5 6
7 8 9
Sample Output
0
因为都是正数,对这个来说仅仅需统计最少的2或5就可以。相对简单。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<string>
#include<iostream>
#include<queue>
#include<cmath>
#include<map>
#include<stack>
#include<bitset>
using namespace std;
#define REPF( i , a , b ) for ( int i = a ; i <= b ; ++ i )
#define REP( i , n ) for ( int i = 0 ; i < n ; ++ i )
#define CLEAR( a , x ) memset ( a , x , sizeof a )
typedef long long LL;
typedef pair<int,int>pil;
const int INF=0x3f3f3f3f;
const int maxn=1010;
int dp[maxn][maxn][2];
int path[maxn][maxn][2];
int mp[maxn][maxn][2];
int n;
void print(int i,int j)
{
if(i==1&&j==1)
return ;
print(path[i][j][0],path[i][j][1]);
if(i-path[i][j][0]==1&&j==path[i][j][1]) printf("%c",'D');
else printf("%c",'R');
}
int main()
{
int x,cnt1,cnt2,temp;
while(~scanf("%d",&n))
{
REPF(i,1,n)
{
REPF(j,1,n)
{
scanf("%d",&x);
cnt1=cnt2=0;temp=x;
while(temp%2==0)
{
temp/=2;
cnt1++;
}
while(x%5==0)
{
x/=5;
cnt2++;
}
mp[i][j][0]=cnt1;
mp[i][j][1]=cnt2;
}
}
CLEAR(dp,INF);
dp[1][1][0]=mp[1][1][0];
dp[1][1][1]=mp[1][1][1];
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
for(int k=0;k<2;k++)//0:2 1:5
{
if(i>1&&dp[i][j][k]>dp[i-1][j][k]+mp[i][j][k])
{
dp[i][j][k]=dp[i-1][j][k]+mp[i][j][k];
path[i][j][0]=i-1;path[i][j][1]=j;
}
if(j>1&&dp[i][j][k]>dp[i][j-1][k]+mp[i][j][k])
{
dp[i][j][k]=dp[i][j-1][k]+mp[i][j][k];
path[i][j][0]=i;path[i][j][1]=j-1;
}
}
}
}
printf("%d\n",min(dp[n][n][0],dp[n][n][1]));
// print(n,n);
// puts("");
}
return 0;
}
/*
再看Codeforces 2B:
Description
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 exceeding109).
Output
In the first line print the least number of trailing zeros. In the second line print the correspondent way itself.
Sample Input
3
1 2 3
4 5 6
7 8 9
0
DDRR
Source
不仅要输出路径。并且矩阵中还带了0,这就是麻烦的地方。
题解:对于要输出的路径。记录前面的一个状态就可以。对于0的处理,假设到终点的2或
5的个数大于等于1了,而矩阵中含0。这时候就是直接答案就是1个0。路径仅仅需找到随意
一个0所在的行列输出就可以。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<string>
#include<iostream>
#include<queue>
#include<cmath>
#include<map>
#include<stack>
#include<bitset>
using namespace std;
#define REPF( i , a , b ) for ( int i = a ; i <= b ; ++ i )
#define REP( i , n ) for ( int i = 0 ; i < n ; ++ i )
#define CLEAR( a , x ) memset ( a , x , sizeof a )
typedef long long LL;
typedef pair<int,int>pil;
const int INF=0x3f3f3f3f;
const int maxn=1010;
int dp[maxn][maxn][2];
int path1[maxn][maxn][2];
int path2[maxn][maxn][2];
int mp[maxn][maxn][2];
int n;
void print1(int i,int j)
{
if(i==1&&j==1)
return ;
print1(path1[i][j][0],path1[i][j][1]);
if(i-path1[i][j][0]==1&&j==path1[i][j][1]) printf("%c",'D');
else printf("%c",'R');
}
void print2(int i,int j)
{
if(i==1&&j==1)
return ;
print2(path2[i][j][0],path2[i][j][1]);
if(i-path2[i][j][0]==1&&j==path2[i][j][1]) printf("%c",'D');
else printf("%c",'R');
}
int main()
{
int x,cnt1,cnt2,temp,ans;
int sx,sy;
while(~scanf("%d",&n))
{
int flag=1;
CLEAR(mp,0);
REPF(i,1,n)
{
REPF(j,1,n)
{
scanf("%d",&x);
cnt1=cnt2=0;temp=x;
if(x==0)
{
mp[i][j][0]=mp[i][j][1]=1;
sx=i;sy=j;flag=0;continue;
}
while(temp%2==0)
{
temp/=2;
cnt1++;
}
while(x%5==0)
{
x/=5;
cnt2++;
}
mp[i][j][0]=cnt1;
mp[i][j][1]=cnt2;
}
}
CLEAR(dp,INF);
dp[1][1][0]=mp[1][1][0];
dp[1][1][1]=mp[1][1][1];
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
for(int k=0;k<2;k++)//0:2 1:5
{
if(i>1&&dp[i][j][k]>dp[i-1][j][k]+mp[i][j][k])
{
dp[i][j][k]=dp[i-1][j][k]+mp[i][j][k];
if(!k)
{
path1[i][j][0]=i-1;
path1[i][j][1]=j;
}
else
{
path2[i][j][0]=i-1;
path2[i][j][1]=j;
}
}
if(j>1&&dp[i][j][k]>dp[i][j-1][k]+mp[i][j][k])
{
dp[i][j][k]=dp[i][j-1][k]+mp[i][j][k];
if(!k)
{
path1[i][j][0]=i;
path1[i][j][1]=j-1;
}
else
{
path2[i][j][0]=i;
path2[i][j][1]=j-1;
}
}
}
}
}
ans=min(dp[n][n][0],dp[n][n][1]);
if(ans>=1&&!flag)
{
printf("%d\n",1);
for(int i=0;i<sx-1;i++)
printf("%c",'D');
for(int i=0;i<sy-1;i++)
printf("%c",'R');
for(int i=sx;i<n;i++)
printf("%c",'D');
for(int i=sy;i<n;i++)
printf("%c",'R');
puts("");
continue;
}
printf("%d\n",ans);
if(ans==dp[n][n][0]) print1(n,n);
else print2(n,n);
puts("");
}
return 0;
}
/*
3
2 2 2
2 2 2
5 5 5
*/
Codeforces #2B The least round way(DP)的更多相关文章
- codeforces 2B The least round way(DP+数学)
The least round way 题目链接:http://codeforces.com/contest/2/problem/B ——每天在线,欢迎留言谈论.PS.本题有什么想法.建议.疑问 欢迎 ...
- Codeforces 2B The least round way(dp求最小末尾0)
题目链接:http://codeforces.com/problemset/problem/2/B 题目大意: 给你一个nxn的矩形,找到一条从左上角到右下角的路径,使得该路径上所有数字的乘积的末尾0 ...
- codeforces 2B The least round way 【DP】
VJ上可找到中文题意. 思路: 首先分解有多少2与多少5.接下来就是dp. 分两次,一次是根据2的数量贪心,另外一次是根据5的数量贪心,看哪一次乘积的末尾0最少. 需要注意的是两点: 1.输入有0的情 ...
- Codeforces 2B. The least round way
There is a square matrix n × n, consisting of non-negative integer numbers. You should find such a w ...
- 最小较小codeforces 2B The least round way
查了好多资料,发现还是不全,干脆自己整理吧,至少保证在我的做法正确的,以免误导读者,也是给自己做个记载吧! 求从左上角到右下角所经过的数字之积末端所含0最小的个数 终究的积可以当作A*2^x*5^y, ...
- CF 2B The least round way DP+Math
题意: 找出一条路, 使每个节点相乘,得到的数末尾 0 最少 每次移动只能向右或者向下, 找到后打印路径 ///按照题目要求,就是找出一条从左上角到右下角中每个数含2 or 5 最少的路 ///可以用 ...
- [CodeForces - 1225E]Rock Is Push 【dp】【前缀和】
[CodeForces - 1225E]Rock Is Push [dp][前缀和] 标签:题解 codeforces题解 dp 前缀和 题目描述 Time limit 2000 ms Memory ...
- [Codeforces 865C]Gotta Go Fast(期望dp+二分答案)
[Codeforces 865C]Gotta Go Fast(期望dp+二分答案) 题面 一个游戏一共有n个关卡,对于第i关,用a[i]时间通过的概率为p[i],用b[i]通过的时间为1-p[i],每 ...
- [Codeforces 553E]Kyoya and Train(期望DP+Floyd+分治FFT)
[Codeforces 553E]Kyoya and Train(期望DP+Floyd+分治FFT) 题面 给出一个\(n\)个点\(m\)条边的有向图(可能有环),走每条边需要支付一个价格\(c_i ...
随机推荐
- SQLState: 23000
今天登陆项目的时候,报500,日志显示如下: 解决办法是: 首先,删除序列:DROP SEQUENCE sys_log_seq 然后,新建序列:CREATE SEQUENCE sys_log_seq ...
- Ngnix SSL配置(HTTP、HTTPS兼容)
一.使用阿里云提供证书 下载aliyun证书for Nginx,解压出两个文件,.pem和.key文件 在nginx安装目录Conf文件夹下新建cert文件夹,拷贝两个密钥文件 二.配置nginx 打 ...
- RabbitMQ系列(六)--面试官问为什么要使用MQ,应该怎么回答
如果简历中有写到使用过RabbitMQ或者其他的消息中间件,可能在MQ方面的第一个问题就是问:为什么要使用MQ 面试官期望的回答 1.项目中有什么业务场景需要用到MQ 2.但是用了MQ,会带来很多问题 ...
- BZOJ 2223: [Coci 2009]PATULJCI 主席树
Code: #include<bits/stdc++.h> #define maxn 300001 #define mid ((l+r)>>1) using namespace ...
- TWaver 3D作品Viewer查看器
为了让开发者更方便的对各类3D模型.设备.物体进行浏览和查看,我们直接封装了mono.Viewer组件.它可以直接根据给定的数据源(json.obj.url等)进行数据加载和浏览展示.对于一般的3D设 ...
- STL源码分析之第二级配置器
前言 第一级是直接调用malloc分配空间, 调用free释放空间, 第二级三就是建立一个内存池, 小于128字节的申请都直接在内存池申请, 不直接调用malloc和free. 本节分析第二级空间配置 ...
- 「 Luogu P1850 」 换教室
解题思路 很明显的是个期望 $dp$. 先前想到 $dp[i][j]$ 表示第决策到第 $i$ 个时间段,已经进行了 $j$ 次申请,然后就没有然后了,因为这根本就没法转移啊,你又不知道前 $i-1$ ...
- <MySQL>入门四 事务控制语言 TCL
-- TCL /* Transcation Control Language 事务控制语言 事务:一个或一组sql语句组成一个执行单元,这个执行单元要么全部执行,要么全部不执行 案例:转账 name ...
- vue 安装+下载
1. npm init -y [生成package.json文件] 2. 增加 "private": true, 3.npm install 4. npm install vue ...
- 【Codeforces 246D】Colorful Graph
[链接] 我是链接,点我呀:) [题意] 让你找到所有和x颜色的点中,和该颜色的点颜色不同的相邻的点的个数(重复颜色算一次) 求出哪种颜色的所要求的点的数量最多. [题解] 对于每一条边只会被查到两次 ...