[CF2B] The least round way - dp

给定由非负整数组成的n×n 的正方形矩阵,你需要寻找一条路径:

以左上角为起点

每次只能向右或向下走

以右下角为终点 并且,如果我们把沿路遇到的数进行相乘,积应当是最小“round”,换句话说,应当以最小数目的0的结尾.

Solution

考虑到最终答案只取决于 \(2,5\) 因子数中最小的那一个,所以可以拆开考虑,然后就是一个朴素的最小和路径dp了

注意如果原矩阵中包含零,答案要和 \(1\) 取 min 一下

#include <bits/stdc++.h>
using namespace std;

vector <int> pat;
int n,a[1005][1005],x[1005][1005],f[1005][1005],ans=1e+9;

void solve(int p) {
    for(int i=1;i<=n;i++) {
        for(int j=1;j<=n;j++){
            a[i][j]=0;
            int t=x[i][j];
            while(t && t%p==0) t/=p, a[i][j]++;
        }
    }
    memset(f,0x3f,sizeof f);
    f[0][1]=0;
    for(int i=1;i<=n;i++) {
        for(int j=1;j<=n;j++) {
            f[i][j]=min(f[i-1][j],f[i][j-1])+a[i][j];
        }
    }
    /*for(int i=1;i<=n;i++) {
        for(int j=1;j<=n;j++) cout<<f[i][j]<<" ";
        cout<<endl;
    }*/
    vector <int> v;
    {
    int p=n,q=n;
    while(p!=1 && q!=1) {
        int i=p, j=q;
        if(f[i][j]==f[i-1][j]+a[i][j]) {
            v.push_back(1); //cout<<"up";
            --p;
        }
        else if(f[i][j]==f[i][j-1]+a[i][j]) {
            v.push_back(0); //cout<<"left";
            --q;
        }
        else cout<<"err";
    }
    while(p!=1) {
        --p;
        v.push_back(1);
    }
    while(q!=1) {
        --q;
        v.push_back(0);
    }
    reverse(v.begin(),v.end());
    if(f[n][n]<ans) {
        ans=f[n][n];
        pat=v;
    }
    }
}

int main() {
    scanf("%d",&n);
    int flag=0,posx,posy;
    for(int i=1;i<=n;i++) {
        for(int j=1;j<=n;j++) {
            scanf("%d",&x[i][j]);
            if(x[i][j]==0) flag=1,posx=i,posy=j;
        }
    }
    solve(2);
    solve(5);
    if(ans>1 && flag) {
        cout<<1<<endl;
        for(int i=1;i<posx;i++) cout<<"D";
        for(int i=1;i<posy;i++) cout<<"R";
        for(int i=posx;i<n;i++) cout<<"D";
        for(int i=posy;i<n;i++) cout<<"R";
        return 0;
    }
    cout<<ans<<endl;
    for(int i=0;i<pat.size();i++) {
        cout<<(pat[i]?"D":"R");
    }
}

原文地址:https://www.cnblogs.com/mollnn/p/12273813.html

时间: 2024-10-13 20:07:36

[CF2B] The least round way - dp的相关文章

CF2B The least round way

CF2B The least round way message1: 脚造的垃圾hack数据: 3 0 1 1 1 1 1 1 1 1 ans: 1 DDRR 数据2: 3 0 1 1 1 1 0 1 1 1 ans: 1 DDRR dp 0由2×5组成 预处理每个位置2因子.5因子个数 f[i][j][k]表示dp到(i,j),k因子至少有几个 输出路径只要倒着dfs一遍即可 代码: #include<bits/stdc++.h> using namespace std; int n; in

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 26 D. Round Subset(dp)

题目链接:Educational Codeforces Round 26 D. Round Subset 题意: 给你n个数,让你选其中的k个数,使得这k个数的乘积的末尾的0的个数最大. 题解: 显然,末尾乘积0的个数和因子2和因子5的个数有关. 然后考虑dp[i][j]表示选i个数,当前因子5的个数为j时,能得到因子2最多的为多少. 那么对于每个数,记录一下因子2和5的个数,做一些01背包就行了. 1 #include<bits/stdc++.h> 2 #define mst(a,b) me

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<cst

CF2B The least round way 题解

都是泪呀...↑ 题目传送门 题意(直接复制了QWQ) 题目描述 给定由非负整数组成的\(n \times n\)的正方形矩阵,你需要寻找一条路径: 以左上角为起点, 每次只能向右或向下走, 以右下角为终点 并且,如果我们把沿路遇到的数进行相乘,积应当是最小"round",换句话说,应当以最小数目的0的结尾. 输入格式 第一行包含一个整数 \((2 \leq n \leq 1000)\),\(n\)为矩阵的规模,接下来的\(n\)行包含矩阵的元素(不超过\(10^9\)的非负整数).

CF 2B The least round way DP+Math

题意: 找出一条路, 使每个节点相乘,得到的数末尾 0 最少 每次移动只能向右或者向下, 找到后打印路径 ///按照题目要求,就是找出一条从左上角到右下角中每个数含2 or 5 最少的路 ///可以用Dp的思想, 然后把每个节点该走的方向记下来 ///再从终点回溯,把路径存入栈,再输出 ///数据会有0的情况, 这时候我们应该记录离终点最近的0 #include<bits/stdc++.h> using namespace std; typedef long long LL; typedef

Codeforces 837D - Round Subset DP

先算出每个数的pop1(twonum),pop(fivenum)然后DP ans[i][j]表示选i个数有j个2时最多有多少个5 转移方程是 for(int j=k;j>=1;j--) { for(int w=pop1;w<5000;w++) { ans[j][w]=max(ans[j][w],ans[j-1][w-pop1]+pop); } } AC程序: #include <bits/stdc++.h> #include <cstring> #include <

C - The Intriguing Obsession /* Codeforces Round #439 */ (dp )

- This is not playing but duty as allies of justice, Nii-chan! - Not allies but justice itself, Onii-chan! With hands joined, go everywhere at a speed faster than our thoughts! This time, the Fire Sisters - Karen and Tsukihi - is heading for somewher

解题报告: CF2B

题目链接:CF2B The least round way 显然需要 \(dp\) 解决. 第一个思路:用 \(dp_{i}{j}\)代表第 \(i\) 行第 \(j\) 列最小的后缀 \(0\) 数,不幸的是,他被 hack 了. 考虑 \(10\)的形成,贡献只来自于 \(2\) 和 \(5\) 这个因数. 我们容易想到最小化 \(\min\{\sum a_i,\sum b_i\}\). ps:\(\sum a_i\) 代表路径中数含有因子 \(2\) 的数量,\(\sum b_i\) 代表