首页 > 其他分享 >小U的问号替换问题 | 动态规划

小U的问号替换问题 | 动态规划

时间:2024-11-07 11:15:00浏览次数:4  
标签:动态 int ll long new include 替换 dp 问号

问题描述

小C拿到了一个由数字字符和 ? 组成的字符串,她的目标是将所有的 ? 替换成数字字符,使得替换后的字符串表示的十进制整数成为正整数 pp 的倍数。由于方案数可能非常大,需要对最终的结果取模 109+7109+7。


测试样例

样例1:

输入:s = "??",p = 1
输出:100

样例2:

输入:s = "????1",p = 12
输出:0

样例3:

输入:s = "1??2",p = 3
输出:34

题解: 

        首先想到使用蛮力法硬解,虽然可能会超时,但是先尝试一下,将每个?字符都用0-9替换一遍,然后就果不其然地超时了。

        然后想到找出字符串代表数字的最大值与最小值,在其中遍历p的倍数,尝试找出匹配的项,也是蛮力求解。

        最后在经过一天的思考后选择了动态规划(确实挺难想的,大概)。定义 dp[i][r] 表示前 i 个字符组成的字符串,其对 p 取模的结果为 r 的方案数。

        初始状态:dp[0][0] = 1,空字符串对 p 取模为 0 的方案数为 1
        状态转移方程:

        1.当s[i]为数字:

        假设当前字符是 digit,则新的模数 new_r 可以通过以下公式计算:

new_r = (r * 10 + digit) % p

        更新 dp[i + 1][new_r]

dp[i + 1][new_r] = (dp[i + 1][new_r] + dp[i][r]) % MOD

        2.当s[i]为问号,则从0-9遍历再进行1步骤。

动态规划代码:

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<iomanip>
#include<queue>
#include<stack>
#include<vector>
#include<set>
#include<map>
#include <functional>
using namespace std;
typedef long long int ll;

const int MOD=1e9+7;

int solution(string s,int p){
    int n=s.size();
    vector<vector<int>> dp(n+1,vector<int>(p, 0));
    dp[0][0]=1;
    for(int i=0;i<n;i++){
        for(int r=0;r<p;r++){
            if(dp[i][r]==0){
                continue;
            }
            if(s[i]=='?'){
                for(char c='0';c<='9';c++){
                    int digit=c-'0';
                    int new_r=(r*10+digit)%p;
                    dp[i+1][new_r]=(dp[i+1][new_r]+dp[i][r])%MOD;
                }
            }
            else{
                int digit=s[i]-'0';
                int new_r=(r*10+digit)%p;
                dp[i+1][new_r]=(dp[i+1][new_r]+dp[i][r])%MOD;
            }
        }
    }
    return dp[n][0];
}

int main() {
    cout << (solution("??", 1) == 100) << endl;
    cout << (solution("????1", 12) == 0) << endl;
    cout << (solution("1??2", 3) == 34) << endl;
    return 0;
}

开始的蛮力法代码:

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<iomanip>
#include<queue>
#include<stack>
#include<vector>
#include<set>
#include<map>
#include <functional>
using namespace std;
typedef long long int ll;

ll sum=0;

ll mystol(string s){
    ll x=0,i=0;
    x=s[0]-48;
    for(i=1;i<s.size();i++){
        x=x*10+(s[i]-48);
    }
    return x;
}

void cmd(string s, int p) {
    // write code here
    int i,j;
    for(i=0;i<s.size();i++){
        if(s[i]=='?'){
            for(j=0;j<10;j++){
                s[i]=(char)j+48;
                //cout << s << "\n";
                cmd(s,p);
            }
            return;
        }

    }
    ll num=mystol(s);
    //cout << num << "\n";
    if(num%p==0){
        sum++;
        //cout << "YES" << "\n";
    }
    return;
}

int solution(string s,int p){
    sum=0;
    cmd(s,p);
    //cout << sum << "\n";
    return sum;
}

int main() {
    cout << (solution("??", 1) == 100) << endl;
    cout << (solution("????1", 12) == 0) << endl;
    cout << (solution("1??2", 3) == 34) << endl;
    cout << (solution("???1??88745???", 11)) << endl;
    return 0;
}
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<iomanip>
#include<queue>
#include<stack>
#include<vector>
#include<set>
#include<map>
#include <functional>
using namespace std;
typedef long long int ll;

int num[10]={0};

string itos(ll x){
    string ans="",t;
    while(x>0){
        t=(x%10+48);
        ans=t+ans;
        x/=10;
    }
    return ans;
}

ll mystol(string s){
    ll x=0,i=0;
    x=s[0]-48;
    for(i=1;i<s.size();i++){
        x=x*10+(s[i]-48);
    }
    return x;
}

ll solution(string s, int p) {
    // write code here
    string mins=s,maxs=s;
    ll i,j,sum=0;
    //
    for(i=0;i<10;i++){
        num[i]=0;
    }
    for(i=1;i<10;i++){
        num[p*i%10]++;
    }
    for(i=0;i<10;i++){
        if(s[s.size()-1]!='?' && num[s[s.size()-1]-48]==0){
            return 0;
        }
    }

    //
    for(i=0;i<s.size();i++){
        if(s[i]=='?'){
            mins[i]='0';
        }
        else{
            mins[i]=s[i];
        }
    }
    for(i=0;i<s.size();i++){
        if(s[i]=='?'){
            maxs[i]='9';
        }
        else{
            maxs[i]=s[i];
        }
    }
    //maxs='1'+ maxs;
    ll maxi=0,mini=0;
    maxi=mystol(maxs);
    mini=mystol(mins);
    mini=((mini/p))*p;
    //cout << maxi << " " << mini << "\n";
    //cout << to_string(1001) << "\n";
    string t=" ";
    for(j=mini;j<=maxi;j+=p){
        //cout << i << "\n";
        t=itos(j);
        //cout << t << "\n";
        while(t.size()<s.size()){
            t='0'+t;
        }
        if(t.size()==s.size()){
            for(i=0;i<s.size();i++){
                if((s[i]>='0' && s[i]<='9' && s[i]!=t[i])){
                    break;
                }
                else if(i==s.size()-1){
                    sum++;
                    //cout << t << "\n";
                }
            }
        }
    }
    //cout << sum << "\n";
    ll a=pow(10,9)+7;
    sum%=a;
    return sum;
}

int main() {
    cout << (solution("??", 1) == 100) << endl;
    cout << (solution("????1", 12) == 0) << endl;
    cout << (solution("1??2", 3) == 34) << endl;
    cout << (solution("78???0?7178213?2", 10)==0 ) << endl;
    return 0;
}

标签:动态,int,ll,long,new,include,替换,dp,问号
From: https://blog.csdn.net/2301_78848414/article/details/143578429

相关文章

  • 刷题总结——动态规划
    总论怎么求解?回溯记忆化搜索递推(方便进行空间复杂度优化)求什么?方案数最大值最小值状态方程对应关系:转移状态的定义(回溯入口)边界条件(边界状态如何递推得到其实状态,回溯的终止条件)如果递推公式是求最小,边界初始化成INT_MAX_*如果递推公式求最大,边界为0或1如......
  • Proteus中数码管动态扫描显示不全(已解决)
    前言我是直接把以前写的51数码管程序复制过来的,当时看的郭天祥的视频,先送段选,消隐后送位选,最后来个1ms的延时。代码在Proteus中数码管静态是可以的,动态显示出了问题——显示不全,我在网上搜的说是Proteus的Bug,需要先送位选再送段选,我试了试也不行。最后在我多次实验下......
  • Vue项目中动态路由与权限控制:router.beforeEach的使用及无token重定向登录页
    在现代前端项目中,权限控制是一个非常重要的环节。VueRouter作为Vue官方的路由管理器,为我们提供了强大的路由管理功能。在本文中,我们将探讨如何在Vue项目中使用router.beforeEach钩子函数来实现动态路由权限控制,并在用户未登录时自动重定向到登录页。步骤一:登录并获取Token首......
  • P1802 5 倍经验日: 动态规划
    5倍经验日题目背景现在乐斗有活动了!每打一个人可以获得5倍经验!absi2011却无奈的看着那一些比他等级高的好友,想着能否把他们干掉。干掉能拿不少经验的。题目描述现在absi2011拿出了$x$个迷你装药物(嗑药打人可耻…),准备开始与那些人打了。由于迷你装药物每个只能用一次,......
  • 数组,静态数组,动态数组
    数组是一个容器,可以存放多个元素这些元素的类型必须是一致的1.静态数组数据类型[]   数组名={元素1,元素2,元素3,.......} 通过数组的下标来引用数组中的元素默认数组下标从0开始到length-1。如果数组下标不在这个范围内会出现下标越界错误引用语法:      ......
  • bug解决记录:前端解密后的中文是问号的解决办法
     最近的项目中,遇到了这个问题,我们的容灾环境要进行演练,但是进行切换到容灾环境的时候,发现返回的中文都是?问号解决思路:1.先看下接口的请求头和响应头是不是指定了这个编码格式。排查出来发现都是有的2.看下解密和加密是否有指定编码格式设置字符byte[]bytes=srcData.getByt......
  • 动态避障-图扑自动寻路 3D 可视化
    自动寻路是机器人导航的核心技术,其原理主要涉及机器人与环境之间的复杂信息交互与处理。在自动寻路过程中,机器人依靠先进的传感器系统,如高清摄像头、精密激光雷达和灵敏超声波装置,全方位感知周围环境。这些传感器能够实时捕捉并分析环境中的障碍物、地形变化和关键路标,为机器人提......
  • Python 使用 Selenium 如何抓取动态网页
    Python动态网页抓取:基础教程在如今的网络中,许多网站是“动态”的,即网页内容不是静态的HTML文件,而是由JavaScript动态生成的。这种动态网页在数据抓取中带来了一些挑战,因为传统的HTML抓取方法无法抓取JavaScript生成的内容。在本教程中,我们将详细介绍如何使用Pyth......
  • 数学建模_BP神经网络模型(多输入多输出)回归模型+Matlab代码包教会使用,直接替换数据
    BP神经网络模型(多输入多输出)回归模型神经网络回归模型原理讲解​该模型是一个典型的多层前馈神经网络(FeedforwardNeuralNetwork,FFNN),应用于回归问题。其基本原理包括数据输入、隐藏层神经元的处理、输出层的预测、以及通过反向传播算法优化权重和偏置的过程。下面将详......
  • ARM-8 代码还原动态调试 pstree 之 out_char
    voidout_char(charc){/*403370: b00001c1 adrp x1,43c000<memcpy@GLIBC_2.17>403374: 9121c021 add x1,x1,#0x870//x1=0x43c870403378: 12001c00 and w0,w0,#0xff//w0=c&0xff40337c: b9401022 ldr w2,[x1,#16]//w2=[0x43c880......