首页 > 其他分享 >P1025 [NOIP2001 提高组] 数的划分 题解

P1025 [NOIP2001 提高组] 数的划分 题解

时间:2023-10-04 18:13:07浏览次数:44  
标签:方案 NOIP2001 int 题解 个数 P1025 开头 dp define

题目传送门

本题共有两种方法,分别是递归深搜和动态规划

方法一:递归深搜

Solution

从小到大一一枚举每一个划分的数,。只要找到一种方案就记录,具体细节代码中有注释。

Code

#include <bits/stdc++.h>
using namespace std;
int n,k,ans;

void dfs(int start,int step,int sum){
    //start表示上一个数,step表示分到了第几个数,
    //sum表示当前已划分数的和 

    if(step==k){
        if(sum==n)ans++;//如果找到一种就记录 
        return ;//剪枝 
    }

    for(int i=start;sum+i*(k-step)<=n;i++)dfs(i,step+1,sum+i);
    //i从start开始枚举,是为了避免重复
    //循环结束条件是为了在枚举过程中要保证后面可以继续划分
}
signed main(){
    cin>>n>>k;

    dfs(1,0,0);

    cout<<ans<<endl;
    return 0;
}

方法二:动态规划

Solution

通过观察可以发现,把n拆分成k个数的方案可以分成两部分:

  1. 以1开头的方案

  2. 不是以1开头的方案

  • 我们发现,以1开头的方案数等于把n-1分成k-1个数的方案数。

为什么呢?

不难发现,所有以1开头的方案除了第一位外,其余数的总和为n-1,个数为k-1,而第一位是固定,因此可以转化为把n-1分成k-1个数的方案数。

  • 观察不是以1开头的方案,可以发现方案数等于把n-k分成k个数的方案数。

这又是为什么呢

我们知道,如果把n-k分成k个数,每一位再加上基数1,就能够满足总和n,和不是以1开头两个条件,也就相当于以1开头的方案

由此我们得到了转移方程

$$ dp[i][j]=dp[i-1][j-1]+dp[i-j][j] $$

其中i是指要划分的数,j是指要划分的个数

Code

#include <bits/stdc++.h>
#define ll long long
#define mod 998244353
#define inf numeric_limits<ll>::max()/2
#define pb push_back
#define sz size
#define fi first
#define se second
#define mkp make_pair
#define pint pair<int,int>
#define pll pair<ll,ll>
#define gcd(a,b) b?gcd(b,a%b):a
#define lcm(a,b) a/(gcd(a,b))*b
#define low_bit(x) x&(-x)
using namespace std;

int n,k;
int dp[210][10];

signed main(){
    cin>>n>>k;
    for(int i=1;i<=n;i++)dp[i][1]=1;//初始化 
    for(int i=1;i<=n;i++){
        for(int j=2;j<=k;j++){//i是指要划分的数,j是指要划分的个数 
            if(i>=j){//只有在i>=j时才能进行数的划分 
                dp[i][j]=dp[i-1][j-1]+dp[i-j][j];
            }
        }
    }
    cout<<dp[n][k]; 
    return 0;
}

//ACplease!!!

标签:方案,NOIP2001,int,题解,个数,P1025,开头,dp,define
From: https://www.cnblogs.com/FrankC/p/17742531.html

相关文章

  • 【题解】Typo
    TypoDescreption求反转一个不合法的括号序列中的一位使其成为一个合法序列的方案数(保证方案一定存在)Solution其实也就是一道较复杂的模拟题先判断哪一类括号数量更多,因为一定是将数量多的括号改成数量少的才有可能变为合法序列,这里就先用左括号举例记录每个位置时没有配对的......
  • CF1234(Div. 3) 题解(A to E)
    AEqualizePricesAgain题解题目大意\(n\)个商品,每个商品价格为\(a_i\),求一个最小的价格\(x\),使得不亏本(即\(\sum\limits_{i=1}^n{(a_i-x)}\ge0\))。解题思路输出平均数向上取整(即\(\left\lceil(\sum\limits_{i=1}^n{a_i})\divn\right\rceil\))即可。代码#include<bit......
  • 项链 题解
    随机化写法很强,但是这里不说。这里只记录数据结构写法。枚举右端点,快速找左端点。首先一种合法的方案中,一种颜色只会有两种情况。全部在区间中及全部在区间外。对于区间外的情况,也就是最后一次出现的位置\(p\)大于右端点\(r\),我们可以维护当前枚举右端点之前的所有颜色非......
  • CF1203(Div. 3) 题解(C to F1)
    由于太懒了,所以不想(会)写\(\texttt{AB}\)和\(\texttt{F2}\)。CCommonDivisors题解题目大意给定一个长度为\(n\)的数列\(\{a_i\}\),求\(\sigma(\gcd\limits_{i\in[1,n]}\{a_i\})\)。解题思路先算出所有元素的最大公因数,如果最大公因数\(g\)为\(1\),即所有元素两两......
  • CF1873(Div. 4) 题解 (A to E)
    AShortSort题解题目大意给定一个长度为\(3\)、由\(a,b,c\)组成的字符串,问可以不变或交换两个字符是的变为\(\texttt{abc}\)。解题思路由于大小固定,所以预处理可行的字符串(仅包含\(\texttt{abcacbbaccba}\))即可。代码#include<bits/stdc++.h>usingnamespacest......
  • 题解 CF1034C【Region Separation】/ SS221116D【Xiong AK 10 IOI】
    很妙的性质题!全是意识流证明见过吗?problem每次选一个非空边集删掉,谓之曰砍树。砍树后需要满足每个连通块的点权和相同。在一个方案中可以砍很多次树,都要满足砍树后的要求。一共有多少种合法方案呢?\(n\leq10^6,1\leqa_i\leq10^9\)。solution假如我们将树砍成\(k\)个连通......
  • 传奇团子师傅题解
    传奇团子师傅题解(模拟退火)申明:本篇题解借鉴了:https://www.luogu.com.cn/blog/SDNetFriend/solution-p7218这篇博客(主要在bitset部分)。题意:给你个矩阵,包含三种颜色,一个美丽串要求你横着或者竖着或者斜着串成一串的三个颜色有特定的顺序,求拿取最多美丽串的方案是什么。题目分......
  • 【UVA 442】Matrix Chain Multiplication 题解(栈)
    假设您必须计算一个表达式,如ABCDE,其中A、B、C、D和E是矩阵。由于矩阵乘法是关联的,所以执行乘法的顺序是任意的。然而,所需的初等乘法的数量很大程度上取决于求值顺序您可以选择。例如,设A为5010矩阵,B为1020矩阵,C为205矩阵。有两个计算ABC的不同策略,即(AB)C和A(B*C)。第一个需要1500......
  • Hadoop问题解决记(2)
     1.发现问题在对HBase集群进行压力测试过程中发现,当实际写入HBase和从HBase查询的量是平时的若干倍时(集群规模10~20台,每秒读写数据量在几十万条记录的量级),导致集群的读写出现一定程度的波动。具体如下:1)写端抛出以下异常信息:org.apache.hadoop.hbase.client.RetriesExha......
  • Hadoop问题解决记(1)
    最近在测试HBase时遇到一个非常奇怪的问题:集群有7台机器,其中1台Master,6台RegionServer。但是Master只能控制其中1台RegionServer,而无法控制其他5台RegionServer。打开master的日志文件,发现以下错误信息:2011-04-2216:37:21,242WARNorg.apache.hadoop.hbase.master.Assignment......