题目链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=4673
题目意思:
给N, K, S 三个数。 用不相同的K 个 不超过N的数 组成 S . 求出一共多少种组合。输入 0 0 结束。
分析:
题目类似于 给你N 种面值硬币,需要一个总值 S, 分成K份。 求分解的方法数。 题目可以用DP来解决。其实也就是一个递推的问题。
DP数组记录的是, 不超过i的 j个不同的数 组成总数 K的总方法数。 可以一开始计算好,求得时候,搜出是哪个值。
#include<stdio.h> #include<cstring> #include<iostream> #include<algorithm> #include<vector> #include<map> using namespace std; int main() { int dp [ 22 ][ 11 ][ 160 ]={0}; int i,j,k; int n,sum,num; while(scanf("%d%d%d",&n,&num,&sum)) { if(n==0&&num==0&&sum==0) break; dp[ 0 ][ 0 ][ 0 ] = 1; for(i=1;i<=n;i++) { for(j=0;j<=num;j++) { for(k = 0; k <= sum; k++ ) { dp [i][j][k]=dp[i-1][j][k]; // 如 9 3 23 能不取9, 求前面的 8 3 23 的方法 if(i <= k && j != 0 ) { dp[i][j][k]+=dp[i-1][j-1][k-i]; // DP数组记录的是, 不超过i的 j个不同的数 组成总数 K的总方法数。 } } } } cout<<dp[n][num][sum]<<endl; } return 0; }