第十八届同济大学程序设计竞赛暨高校网络友谊赛 C.困难的数学题 (dp递推)

-
题意:将\(n\)划分成小于\(k\)的正整数之和的方案数.
-
题解:设\(dp[i]\)为\(i\)的方案数,因为最小的能取的数是\(k\),所以\(dp[i]=dp[i-k]+dp[i-k-1]+...dp[0]\),这样转移过来,而\(dp[i-1]=dp[i-k-1]+dp[i-k-2]+...+dp[0]\),所以可以得到:\(dp[i]=dp[i-k]+dp[i-1]\).
-
代码:
#include <bits/stdc++.h> #define ll long long #define fi first #define se second #define pb push_back #define me memset #define rep(a,b,c) for(int a=b;a<=c;++a) #define per(a,b,c) for(int a=b;a>=c;--a) const int N = 1e6 + 10; const int mod = 1e9 + 7; const int INF = 0x3f3f3f3f; using namespace std; typedef pair<int,int> PII; typedef pair<ll,ll> PLL; ll gcd(ll a,ll b) {return b?gcd(b,a%b):a;} ll lcm(ll a,ll b) {return a/gcd(a,b)*b;} ll n,k; ll dp[N]; int main() { ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); cin>>n>>k; dp[k]=1; for(int i=k+1;i<=n;++i){ dp[i]=(dp[i-1]+dp[i-k])%mod; } cout<<dp[n]<<'\n'; return 0; }
𝓐𝓬𝓱𝓲𝓮𝓿𝓮𝓶𝓮𝓷𝓽 𝓹𝓻𝓸𝓿𝓲𝓭𝓮𝓼 𝓽𝓱𝓮 𝓸𝓷𝓵𝔂 𝓻𝓮𝓪𝓵
𝓹𝓵𝓮𝓪𝓼𝓾𝓻𝓮 𝓲𝓷 𝓵𝓲𝓯𝓮

浙公网安备 33010602011771号