Codeforces #2B B. The least round way

#include <iostream>
第四题:这题求一条路径上的数,使得这些数相乘后后边的0的个数最少

分析:这题一看就是DP问题,但是需要数学的一点分析,当时我一看就吓到了(数学弱渣T_T),然后去做E题了

对于表格中有0的情况,答案最多为1,路径便是通过这个点的路径;或者为0;咱们先抛弃这种情况不谈,把0当作10处理

 #include <cstdio> #include <cstdlib> #include <cstring> #include <algorithm> #include <cmath> #include <string> #define N 1007 using namespace std; int g[2][N][N]; int dp[2][N][N]; int zx,zy; int mat[2][N][N]; char path[4*N]; int n; int solve(int mk){ int i,j; g[mk][1][1] = 0; dp[mk][1][1] = mat[mk][1][1]; for (i = 1; i <= n; ++i){ for (j = 1; j <= n; ++j){ if (i == 1 && j == 1) continue; if (i == 1){ dp[mk][i][j] = dp[mk][i][j - 1] + mat[mk][i][j]; g[mk][i][j] = 1; } else if (j == 1){ dp[mk][i][j] = dp[mk][i - 1][j] + mat[mk][i][j]; g[mk][i][j] = 0; } else{ int tp1 = dp[mk][i - 1][j]; int tp2 = dp[mk][i][j - 1]; if (tp1 < tp2){ dp[mk][i][j] = dp[mk][i - 1][j] + mat[mk][i][j]; g[mk][i][j] = 0; } else{ dp[mk][i][j] = dp[mk][i][j - 1] + mat[mk][i][j]; g[mk][i][j] = 1; } } } } return dp[mk][n][n]; } void Path(int mk,int x,int y){ if (x == 1 && y == 1) return ; else if (g[mk][x][y] == 0){ Path(mk,x - 1,y); printf("D"); } else{ Path(mk,x,y - 1); printf("R"); } } int main(){ int i,j; int x; bool flag = false; scanf("%d",&n); for (i = 1; i <= n; ++i){ for (j = 1; j <= n; ++j){ mat[0][i][j] = mat[1][i][j] = 0; scanf("%d",&x); if (x == 0){ zx = i; zy = j; flag = true; continue; } int tmp = x; while (tmp % 2 == 0){ mat[0][i][j]++; tmp /= 2; } tmp = x; while (tmp % 5 == 0){ mat[1][i][j]++; tmp /= 5; } } } int ans1 = solve(0); int ans2 = solve(1); int ans,mk; if (ans1 < ans2){ ans = ans1; mk = 0; } else{ ans = ans2; mk = 1; } if (flag&&ans>1){ printf("1\n"); for (i = 2; i <= zx; ++i) printf("D"); for (i = 2; i <= n; ++i) printf("R"); for (i = zx + 1; i <= n; ++i) printf("D"); printf("\n"); } else{ printf("%d\n",ans); Path(mk,n,n); printf("\n"); } return 0; }

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值