1~n的之间的k个数组成和为n的方案数(动态规划)

绯色的子弹

Description

众所周知,夏季奥林匹克运动会时隔56年第二次在东京举办,紧接着出来的《名侦探柯南 M24绯色的子弹》竟也是有奥运会的背景,最重要的是重归主线!!!(赤井秀一好帅)

讲个笑话:太让我失望了,这次剧场版居然不是讲赤井秀一参加奥运射击项目吊打各路高手包揽所有金牌的,千载难逢的机会啊[蛆音娘_滑稽]

阿笠博士带着包括柯南在内的少年侦探团在奥运会现场,大家都知道,阿笠博士有个猜谜语的习惯,今天阿笠博士给出了这样一个题目:

给定两个整数nnnkkk,含义为用恰好kkk个正整数数字组合为和为nnn的方案数,对于n=4,k=2n=4,k=2n=4,k=2,{1,31,313}和{3,13,13,1}是两种方案,还有一点就是得保证,组合成答案的这kkk个数各不相同,所以{2,22,22,2}不能算是一种方案,那么下面就由聪明的你来代替侦探团来解答这个问题吧。

Input

输入包括一行,两个整数,分别是n,k(1≤ n≤200,1≤k≤10)n,k(1 \leq  n \leq 200,1 \leq k \leq 10)n,k1 n200,1k10

Output

扫描二维码关注公众号,回复: 10399449 查看本文章

输出只有一个整数,也就是答案。

Sample Input 1

10 2

Sample Output 1

8

Sample Input 2

100 3

Sample Output 2

4704

Source

nuoyanli

思路

这题说实话,到现在我还不是太理解这 dp 的思路

代码

#include<iostream>
using namespace std;

#define ll long long 
ll dp[15][205];             //dp[i][j] 表示由i个数的和组成的值 j

int main()
{
    /* freopen("A.txt","r",stdin); */
    int n, k;
    scanf("%d %d", &n, &k);
    //初始(只有从dp[0][0] 转化过来的方案才可行)
    dp[0][0] = 1;
    
    for(int i = 1; i <= n; i ++)                //这次我们选择加的数是 i
        for(int j = k; j >= 1; j --)            //假设组成的数的数量为 j 个
            for(int u = n; u >= i; u --)        //u是我们要假设的数
                dp[j][u] += dp[j - 1][u - i];

    ll ans = dp[k][n];

    //乘以全排
    for(ll i = 1; i <= k; i ++)
        ans *= i;
    printf("%lld\n", ans);

    return 0;
}
发布了159 篇原创文章 · 获赞 243 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/qq_34261446/article/details/105157592