返回顶部

第十八届同济大学程序设计竞赛暨高校网络友谊赛 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;
    }
    
    
posted @ 2021-05-22 23:08  _Kolibri  阅读(117)  评论(0)    收藏  举报