首页 > 其他分享 >Codeforces Beta Round #2--B题 (DP)

Codeforces Beta Round #2--B题 (DP)

时间:2023-05-31 17:38:07浏览次数:60  
标签:dp5 dp2 -- ++ Codeforces int Beta MAXN m2


题目:The least round way

 

1000*1000的方阵,每个格子有一个非负整数,现在要从左上走到右下,每次只能向下或者向右走。目标是使得所有走的格子里的数的乘积里,末尾0的个数最少,要求输出最有解和走法。

不用怎么想也知道基本是个dp了,可以发现其实只有2和5的因子是有用的,但是如果状态同时记录2和5的因子个数的话,就不好表示了。其实方法很简单,对2个5分别做一次,第一次让2尽量少,第二次让5尽量少,两个里面取个最小的就是答案了,应该不难证明。dp过程就比较普通了,记录下路径,最后输出即可,不再赘述。

当然,本题是有一个比较大的trick的,就是如果其中有一个数字为0,那么最后的乘积可以为0,也就是答案至少可以是1。因此,只要先记录下方阵中有没有0,然后dp的时候强制不走0,最后输出走0和不走0的最优解即可。

#include <cstdio>
#include <algorithm>

using namespace std;

const int MAXN = 1024;
int m2[MAXN][MAXN];
int m5[MAXN][MAXN];
int l2[MAXN][MAXN];
int l5[MAXN][MAXN];
int dp2[MAXN][MAXN];
int dp5[MAXN][MAXN];
int n;
int zx, zy;

void output(int ll[MAXN][MAXN], int x, int y)
{
    if (x == 0 && y == 0)
        return;
    if (ll[x][y] == 0)
    {
        output(ll, x - 1, y);
        putchar('D');
    }
    else
    {
        output(ll, x, y - 1);
        putchar('R');
    }
}

int main()
{
    scanf("%d", &n);
    zx = zy = -1;
    for (int i = 0; i < n; ++i)
    {
        for (int j = 0; j < n; ++j)
        {
            scanf("%d", &m2[i][j]);
            if (m2[i][j] != 0)
            {
                m5[i][j] = 0;
                while (m2[i][j] % 5 == 0)
                {
                    ++m5[i][j];
                    m2[i][j] /= 5;
                }
                int t = 0;
                while (m2[i][j] % 2 == 0)
                {
                    ++t;
                    m2[i][j] /= 2;
                }
                m2[i][j] = t;
            }
            else
            {
                zx = i;
                zy = j;
                m2[i][j] = m5[i][j] = -1;
            }
        }
    }
    for (int i = 0; i < n; ++i)
    {
        for (int j = 0; j < n; ++j)
        {
            if (m2[i][j] == -1)
                dp2[i][j] = -1;
            else
            {
                if (i == 0 && j == 0)
                    dp2[i][j] = m2[i][j];
                else
                {
                    dp2[i][j] = 100000000;
                    if (i > 0 && dp2[i - 1][j] != -1 && dp2[i - 1][j] + m2[i][j] < dp2[i][j])
                    {
                        dp2[i][j] = dp2[i - 1][j] + m2[i][j];
                        l2[i][j] = 0;
                    }
                    if (j > 0 && dp2[i][j - 1] != -1 && dp2[i][j - 1] + m2[i][j] < dp2[i][j])
                    {
                        dp2[i][j] = dp2[i][j - 1] + m2[i][j];
                        l2[i][j] = 1;
                    }
                    if (dp2[i][j] == 100000000)
                        dp2[i][j] = -1;
                }
            }
        }
    }
    for (int i = 0; i < n; ++i)
    {
        for (int j = 0; j < n; ++j)
        {
            if (m5[i][j] == -1)
                dp5[i][j] = -1;
            else
            {
                if (i == 0 && j == 0)
                    dp5[i][j] = m5[i][j];
                else
                {
                    dp5[i][j] = 100000000;
                    if (i > 0 && dp5[i - 1][j] != -1 && dp5[i - 1][j] + m5[i][j] < dp5[i][j])
                    {
                        dp5[i][j] = dp5[i - 1][j] + m5[i][j];
                        l5[i][j] = 0;
                    }
                    if (j > 0 && dp5[i][j - 1] != -1 && dp5[i][j - 1] + m5[i][j] < dp5[i][j])
                    {
                        dp5[i][j] = dp5[i][j - 1] + m5[i][j];
                        l5[i][j] = 1;
                    }
                    if (dp5[i][j] == 100000000)
                        dp5[i][j] = -1;
                }
            }
        }
    }
    if (dp2[n - 1][n - 1] == -1)
    {
        printf("1\n");
        for (int i = 0; i < n - 1; ++i)
            putchar('D');
        for (int i = 0; i < n - 1; ++i)
            putchar('R');
        puts("");
    }
    else
    {
        int now = min(dp2[n - 1][n - 1], dp5[n - 1][n - 1]);
        if (zx != -1 && now >= 1)
        {
            printf("1\n");
            for (int i = 0; i < zx; ++i)
                putchar('D');
            for (int i = 0; i < n - 1; ++i)
                putchar('R');
            for (int i = zx; i < n - 1; ++i)
                putchar('D');
            puts("");
        }
        else
        {
            printf("%d\n", now);
            if (dp2[n - 1][n - 1] < dp5[n - 1][n - 1])
                output(l2, n - 1, n - 1);
            else
                output(l5, n - 1, n - 1);
            puts("");
        }
    }
    return 0;
}

 

标签:dp5,dp2,--,++,Codeforces,int,Beta,MAXN,m2
From: https://blog.51cto.com/u_16146153/6388585

相关文章

  • HDU1016(DFS)
    题目:PrimeRingProblem #include<stdio.h>#include<string.h>#defineN105intn;inta[25];boolvisited[25];boolprime[N];voidisprime(){inti,j;memset(prime,true,sizeof(prime));for(i=2;i<N;i++){for(j=i+......
  • HTML基础学习
    1.HTML表单元素的使用<!doctypehtml><html><head><title>NEFU</title></head><body><center><h2><fontcolor="blue">中国百度</font></h2> <ahref="http://www.......
  • POJ2352 stars(树状数组)
    题目:Stars #include<stdio.h>#include<string.h>constintN=32005;intC[N];intlevel[N];intLowbit(intx){returnx&(-x);}voidUpdate(intx){inti;for(i=x;i<=N;i+=Lowbit(i)){C[i]++;}}i......
  • 动态库版本控制
    Linux中有一套规则来命名系统中的每一个共享库,它规定共享库的命名规则必须如下libname.so.x.y.z最前面使用前缀“lib”、中间是库的名字和后缀“.so”,最后面跟着的是三个数字组成的版本号。“x”表示主版本号,“y”表示次版本号,“z”表示发布版本号。   发布版本号表示......
  • 欧伟杰:乘“20+8”政策之东风,促进深圳空间数据向好发展
    5月18日,由中地数码、深圳市城市公共安全技术研究院和深圳计算科学研究院(以下简称:深算院)联合主办的“2023自主可控GIS技术创新与应用发展论坛”在深圳成功召开。会后,深算院YashanDB研发总监欧伟杰博士接受了深圳特区报读特新闻的采访。(注:本文转载自读特官网)“深圳作为科创之都,数字经......
  • HDU1403(后缀数组--最长公共子串)
    题目:LongestCommonSubstring题意:判断给定的两个串中,最长的公共串。思路:将它们合并为一个串,然后利用后缀数组求解。首先是二倍增算法:时间复杂度为O(n*log(n))#include<stdio.h>#include<string.h>#definemax1000010intwa[max],wb[max],wv[max],ws[max];intrank[max],he......
  • HDU4259(简单群置换)
    题目:DoubleDealing#include<iostream>#include<string.h>#defineLLlonglongconstintN=1005;intn,k;inta[N][N];boolf[N];intnum[N];LLgcd(LLa,LLb){returnb?gcd(b,a%b):a;}intmain(){inti,j;while(std::cin>......
  • Jenkins(单独部署非容器版本)配置k8s【转】
    一、安装kubernetes插件1.在插件管理里面搜索kubernetes,如下图:点击manageJenkins进入配置页面:点击插件管理:搜索kubernetes插件:2.检查是否安装成功点击ManagerJenkins进入配置界面,然后点击ConfigureSystem:在系统配置里面可以找到Cloud配置项,则表示插件安装成功:注意:我这里......
  • HDU1058 Humble Numbers
    题目:HumbleNumbers humblenumber从1为"始祖",剩下的所有数,其实都是在此基础上乘以2,3,5,7演化出来的,代码主要语句:f[t]=min(2*f[i],3*f[j],5*f[k],7*f[l]);#include<iostream>#include<stdio.h>usingnamespacestd;intf[5843],n;inti,j,k,l;intmin(inta,intb,int......
  • next_permutation函数
    next_permutation的函数声明:#include <algorithm> boolnext_permutation(iteratorstart,iteratorend);next_permutation函数的返回值是布尔类型,在STL中还有perv_permutation()函数 #include<iostream>#include<algorithm>#include<string>usingnamespacest......