codeforces2b the least round way

给出一个矩阵,求从左上角到右下角找出一条路径,使得这条路径上的所有数的乘积后缀0最小。从左上角至右下角的输出路径。

  1 #include <iostream>
  2 #include <stdio.h>
  3 #include <stdlib.h>
  4 #include <math.h>
  5 #include <string.h>
  6 #include <algorithm>
  7 using namespace std;
  8 const int maxn=1005;
  9 int dp[maxn][maxn][4];
 10 int n,len;
 11 char s[2*maxn];
 12 /**
 13 解题思路:
 14 0的个数是有2*5来决定的.对于每个数,质因子分解出2,5的个数。
 15 找出2个数最小的路径l1上最后一个点的2的个数k
 16 找出5个数最小的路径l2上最后一个点的5的个数m
 17 对于l1来说,l2路径上最后一个点的2的个数会不小于k.
 18 对于l2来说,l1路径上最后一个点的5的个数会不小于m.
 19 所以要想使得后缀0最小,也就是min(k,m)最小的数就是解,
 20 对应路径输出即可。
 21 注意0的情况。
 22 0不存在 直接输出路径
 23 0存在,MIN>=1输出可行0路径
 24 0存在,MIN<1输出路径
 25 dp[i][j][0]从左上角到i,j点2的个数最小
 26 dp[i][j][1]从左上角到i,j点5的个数最小
 27 dp[i][j][2]到达2的方向
 28 dp[i][j][3]到达5的方向
 29
 30 */
 31 void work(int k)
 32 {
 33     int x=n,y=n;
 34     while(x>=1&&y>=1)
 35     {
 36         s[len++]=dp[x][y][k];
 37         if(dp[x][y][k]==‘D‘) x=x-1;
 38         else y=y-1;
 39         if(x==1&&y==1) break;
 40     }
 41 }
 42 int main()
 43 {
 44     int num,flag;
 45     while(scanf("%d",&n)!=EOF)
 46     {
 47         flag=0;
 48         memset(dp,0,sizeof(dp));
 49         for(int i=0; i<=n; i++)
 50         {
 51             dp[0][i][0]=dp[i][0][1]=dp[i][0][0]=dp[0][i][1]=99999999;
 52         }
 53         for(int i=1; i<=n; i++)
 54         {
 55             for(int j=1; j<=n; j++)
 56             {
 57                 scanf("%d",&num);
 58                 if(num==0) flag=i;
 59                     while(num&&num%2==0)
 60                     {
 61                         dp[i][j][0]++;
 62                         num/=2;
 63                     }
 64                 while(num&&num%5==0)
 65                 {
 66                     dp[i][j][1]++;
 67                     num/=5;
 68                 }
 69                 if(i==1&&j==1) continue;
 70                 if(i==1&&j>1)
 71                 {
 72                     dp[i][j][2]=dp[i][j][3]=‘R‘;
 73                     dp[i][j][0]+=dp[i][j-1][0];
 74                     dp[i][j][1]+=dp[i][j-1][1];
 75                     continue;
 76                 }
 77                 if(i>1&&j==1)
 78                 {
 79                     dp[i][j][2]=dp[i][j][3]=‘D‘;
 80                     dp[i][j][0]+=dp[i-1][j][0];
 81                     dp[i][j][1]+=dp[i-1][j][1];
 82                     continue;
 83                 }
 84                 if(dp[i][j-1][0]<dp[i-1][j][0])
 85                 {
 86                     dp[i][j][0]+=dp[i][j-1][0];
 87                     dp[i][j][2]=‘R‘;
 88                 }
 89                 else
 90                 {
 91                     dp[i][j][0]+=dp[i-1][j][0];
 92                     dp[i][j][2]=‘D‘;
 93                 }
 94                 if(dp[i][j-1][1]<dp[i-1][j][1])
 95                 {
 96                     dp[i][j][1]+=dp[i][j-1][1];
 97                     dp[i][j][3]=‘R‘;
 98                 }
 99                 else
100                 {
101                     dp[i][j][1]+=dp[i-1][j][1];
102                     dp[i][j][3]=‘D‘;
103                 }
104             }
105         }
106         int ans5=dp[n][n][1],ans2=dp[n][n][0];
107         len=0;
108         if(flag&&min(ans2,ans5)>=1)///没有考虑   存在0并且结果为0的情况
109         {
110             printf("1\n");
111             for(int i=1; i<flag; i++) printf("D");
112             for(int i=1; i<n; i++) printf("R");
113             for(int i=flag; i<n; i++) printf("D");
114             printf("\n");
115         }
116         else
117         {
118             if(ans2<ans5)
119             {
120                 printf("%d\n",dp[n][n][0]);
121                 work(2);
122             }
123             else
124             {
125                 printf("%d\n",dp[n][n][1]);
126                 work(3);
127             }
128             for(int i=len-1; i>=0; i--)
129                 printf("%c",s[i]);
130             printf("\n");
131         }
132     }
133     return 0;
134 }

时间: 2024-11-09 02:11:21

codeforces2b the least round way的相关文章

codeforces2B - The least round way DP

题意:给你一个矩阵,问你从左上角走一直走到右下角只能向右向下,问你最后乘起来尾数0个数最少的数值和路径是什么 解题思路:可以知道 要么这条路径上和 的质因子  2 的个数 < 5的个数, 要么 5的个数 < 2 的个数,所以就在一个节点里面添加两个信息,一种是2最小 ,一种是5最小, 最开始没注意看数据  莫名 RE 31组数据,然后发现有0,这里特判一下就行了,写了200行也是给自己跪了. 解题代码: 1 // File Name: 2b.cpp 2 // Author: darkdream

Educational Codeforces Round 21 G. Anthem of Berland(dp+kmp)

题目链接:Educational Codeforces Round 21 G. Anthem of Berland 题意: 给你两个字符串,第一个字符串包含问号,问号可以变成任意字符串. 问你第一个字符串最多包含多少个第二个字符串. 题解: 考虑dp[i][j],表示当前考虑到第一个串的第i位,已经匹配到第二个字符串的第j位. 这样的话复杂度为26*n*m*O(fail). fail可以用kmp进行预处理,将26个字母全部处理出来,这样复杂度就变成了26*n*m. 状态转移看代码(就是一个kmp

SnackDown Online Pre-elimination round A

1. 应该n是偶数,就行吧.应该判断1个人,只能出现一次吧. 1 #include<bits/stdc++.h> 2 #define pb push_back 3 typedef long long ll; 4 using namespace std; 5 typedef pair<int, int> pii; 6 const int maxn = 1e3 + 10; 7 8 void yes() {cout << "yes" << en

code force 2B 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 bott

MySQL中ROUND和TRUNCATE的区别

1.ROUND可以进行四舍五入,按照对应的位数 2.TRUNCATE直接按照位数截取,不四舍五入 实例: SELECT ROUND(RAND(),4),TRUNCATE(RAND(),4); 版权声明:本文为博主原创文章,未经博主允许不得转载.

Codeforces 837D Round Subset(背包)

题目链接  Round Subset 题意  在n个数中选择k个数,求这k个数乘积末尾0个数的最大值. 首先我们预处理出每个数5的因子个数c[i]和2的因子个数d[i] 然后就可以背包了. 设f[i][j]为选i个数,5的因子总和为j时,2的因子总和的最大值. 则状态转移方程为 $f[i][j] = max(f[i - 1][j - c[k]] + d[k])$ 注意边界条件 时间复杂度$O(5200nk)$ #include <bits/stdc++.h> using namespace s

poj3252 Round Numbers

Round Numbers POJ - 3252 题目大意: 输入两个十进制正整数a和b,求闭区间[a,b]内有多少个Round Number? 所谓的Round Number就是一个把十进制数转换成一个无符号二进制数,若该二进制数中0的个数大于等于1的个数,则它就是一个Round Number. 注意 转换所得的二进制数,最高位必然是1,最高位前不允许有0 /* 以前用的组合数学,听说dalao也用数位dp做,我也来一下 */ #include<iostream> #include<c

Codeforces Round #428 (Div. 2)

Codeforces Round #428 (Div. 2) A    看懂题目意思就知道做了 #include<bits/stdc++.h> using namespace std; #pragma comment(linker, "/STACK:102400000,102400000") #define rep(i,a,b) for (int i=a; i<=b; ++i) #define per(i,b,a) for (int i=b; i>=a; --i

LibreOJ #515. 「LibreOJ β Round #2」贪心只能过样例

二次联通门 : LibreOJ #515. 「LibreOJ β Round #2」贪心只能过样例 /* LibreOJ #515. 「LibreOJ β Round #2」贪心只能过样例 很显然 贪心方程哦不 dp方程为 f[i][j]=f[i-1][j-k*k] 但是这样的话复杂度就是O(N ^ 5) 那么就用bitset优化一下 就ok了 */ #include <iostream> #include <cstdio> #include <bitset> void