首页 > 其他分享 >洛谷题单指南-动态规划2-P1874 快速求和

洛谷题单指南-动态规划2-P1874 快速求和

时间:2024-04-25 18:13:28浏览次数:25  
标签:剪枝 P1874 求和 洛谷题 sum 整数 int 枚举 字符串

原题链接:https://www.luogu.com.cn/problem/P1874

题意解读:一个数字字符串s,分解成几个整数,和为n,计算最少加号个数,也就是计算最少分解的整数个数-1。

解题思路:此题虽然分类在动态规划,但数据量不大,DFS更加直观和易于理解,所以采用DFS暴搜+剪枝来解决。

搜索思路是对数字字符串依次枚举前1/2/3/4...个数字组成整数,直到整数超过目标和,然后递归处理字符串剩下的部分,同时目标和减去前面的整数。

要想不超时,需要进行合理的剪枝:

剪枝1:当枚举到字符串前面的整数是0,且不是最后一位时,没必要继续往下递归,这样的拆分是多余的,要去除前导0,继续往后枚举

剪枝2:当枚举到字符串前面的整数大于目标和,没必要再枚举下去,直接退出循环

剪枝3:当枚举到字符串前面的整数后,剩下部分的整数如果比剩下的目标和小,那么继续讲剩下的字符串拆分之后的和会越来越小,没必要再枚举下去,退出循环

100分代码:

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

string s;
int n;
int ans = INT_MAX;

//从字符串s的start开始,挑选出若干整数之和等于sum,cnt记录有多少个整数
void dfs(int start, int sum, int cnt)
{
    if(start == s.size() && sum == 0)
    {
        ans = min(ans, cnt - 1); //加号数量是整数数量-1
        //cout << cnt - 1 << endl;
        return;
    }
    int num = 0;
    for(int i = start; i < s.size(); i++)
    {
        num = 10 * num + s[i] - '0'; //枚举前0~i数字组成的整数
        if(num == 0 && i < s.size() - 1) continue; //剪枝1:整数的前导0没必要单独抽取出来,最后的0需要单独抽取出来
        if(num > sum) break; //剪枝2:如果整数超过sum,结束,因为再往后num更大
        if( s.size() - i <= 15)
        {
            long long remain = 0;
            for(int j = i; j < s.size(); j++)
            {
                remain = 10 * remain + s[j] - '0';
            }
            if(remain < sum - num) break; //剪枝3:如果字符串剩下部分的整数比sum-num还小,后续的划分只会越来越小,可以结束
        }
        dfs(i + 1, sum - num, cnt + 1); //前0~i个数字划为一个整数,继续处理后面的数字,'+'加1
    }
}

int main()
{
    cin >> s >> n;
    dfs(0, n, 0);
    if(ans == INT_MAX) cout << -1;
    else cout << ans;
    return 0;
}

 

标签:剪枝,P1874,求和,洛谷题,sum,整数,int,枚举,字符串
From: https://www.cnblogs.com/jcwy/p/18158294

相关文章

  • 洛谷题单指南-动态规划2-P4933 大师
    原题链接:https://www.luogu.com.cn/problem/P4933题意解读:求有多少个子序列可以组成等差序列解题思路:1、暴力DFS如果实在想不出动规的方法,对于n<=20的数据,可以DFS枚举所有子序列的子集,再判断是否是等差数列。30分代码:#include<bits/stdc++.h>usingnamespacestd;const......
  • 洛谷题单指南-动态规划2-P1725 琪露诺
    原题链接:https://www.luogu.com.cn/problem/P1725题意解读:走过一系列格子之后,冰冻指数之和最大,相当于计算最大子序列的和。解题思路:设a[0~n]保存所有冰冻指数设dp[i]表示以第i号格子为终点所能获得的最大冰冻指数设j表示i的前一个格子,也就是从j可以移动到i已知i,则j的范围也......
  • Vue--POST请求和GET请求
    1、POST请求(POST请求原则上都要传参数,下面介绍两种传参数的方法)1.1POST请求传参方法1--字典类型参数Vue前端代码<template><formclass="form-inlinepanel-body"id="formData"><div><label>账号</label><inpu......
  • 洛谷题单指南-动态规划2-P1020 [NOIP1999 提高组] 导弹拦截
    原题链接:https://www.luogu.com.cn/problem/P1020题意解读:拦截系统发射导弹的高度依次不增,计算能拦截的最大导弹数以及需要几套拦截系统。解题思路:问题1:最多能拦截多少导弹?由于发射导弹高度不增,所以求一个最长不增子序列即可得到最大拦截数。方法一、O(n^2)做法:动态规划。采......
  • DataTable 过滤、求和、去重
    DataTable过滤、求和、去重//多个多个重复去除//去掉factoryCode,recWeek,materialNo,quantity,recDate,uploadDate相同的重复数据DataViewdv=newDataView(dt);//dt=dv.ToTable(true,"factoryCode,recWeek,materialNo,quantity,recDate,uploadDate");//求和......
  • 洛谷题单指南-动态规划1-P1064 [NOIP2006 提高组] 金明的预算方案
    原题链接:https://www.luogu.com.cn/problem/P1064题意解读:用固定钱数购买最大价值的物品。解题思路:背包问题,背包问题里的体积相当于物品价格,价值相当于价格*重要度物品分为主件、附件,主件最多有0/1/2个附件,要选附件必须选相应主件,因此在递推计算dp[j]总价格j能购买的最大价......
  • 洛谷题单指南-动态规划1-P3842 [TJOI2007] 线段
    原题链接:https://www.luogu.com.cn/problem/P3842题意解读:计算1-n的最短路,且每行要覆盖线段。解题思路:既然要每行覆盖线段,那往下一行走时,必然是从线段的端点往下,有可能是从左端点往下,也有可能是从右端点往下。当已知第i行,从1走到第i行的左端点且要覆盖第i行线段的路程可以计算......
  • Flask请求和响应
    Flask请求和响应目录Flask请求和响应flask请求对象request参数args-Get参数获取form-POST请求参数JSONrequest.values路径属性路由转化器自定义转换器flask响应返回返回json自定义响应对象重定向Cookies对象Cookie的特点Session会话对象Session的特点参考资料flask请求对象使用......
  • L1-009 N个数求和
    #include<bits/stdc++.h>usingnamespacestd;constintinf=0x3f3f3f3f;#definelllonglongstructFraction{ llfenzi,fenmu;};intgcd(inta,intb){ if(b==0)returna; returngcd(b,a%b);}intlcm(inta,intb){ returna/gcd(a,b)*b;}Fracti......
  • 洛谷题单指南-动态规划1-P1077 [NOIP2012 普及组] 摆花
    原题链接:https://www.luogu.com.cn/problem/P1077题意解读:n种花选m个的选法,每种花数量为ai。解题思路:设dp[i][j]表示前i种花选j个的选法对于第i种花,可以选0,1,2...min(ai,j)个则有递推式:dp[i][j]=∑dp[i-1][j-k],k取0,1,2...min(ai,j)初始化dp[0][0]=1100分代码:#incl......