描述
Given n objects you’d have to tell how many different groups can be chosen if r objects are taken at a time.
输入
Input consists of less than 100 test cases. Each test case begins with two integers n (0 < n <= 50), m (0 <= m <= n). The next line will contain the labels (numbers in the range 1 to n) of the n objects you are to choose from. Two objects with the same label are considered equivalent. Then in the last line for that test case, you’d have m values for r. There will be a single space separating two consecutive numbers in a line. Input is terminated by a test case where n=0, you must not process this test case.
输出
For each test case, print the test case number. And for each query number r, print the number of different groups that can be formed if r objects are taken from the given n objects. You can assume that for all input cases, the output will always fit in a 64-bit unsigned integer and (0<=r<=n).
样例输入
5 2
1 2 3 4 5
2 1
4 1
1 2 3 4
2
0 0
样例输出
Case 1:
10
5
Case 2:
6
像这种定量计算不同的解决方案就可以归结为背包问题
我们可以把他转换成一个背包问题,把每次选择的object的个数当成是背包容量,满足背包容量的方案就是 the number of different groups.
object[]数组来存储输入的数字
我们用一个二维数组result[][]来表示结果,result[s][r]表示从object[s]开始计算选取r容量的方案个数,所以result[s][r]=result[s+1][r-1]+result[k][r],其中result[s+1][r-1]表示把object[s]放入背包中后的方案个数;result[k][r]表示忽略object[s],并找到和object[s]不相等的object[k]时的解决方案的个数。
你会发现result[s][r]=result[s+1][r-1]+result[k][r],背包问题在解决的时候是需要知道后面的值的,所以需要从后面开始计算,但是背包的容量是在递减的,所以开始的位置是从object的后面开始,容量从1开始
初始化时 result[i][0]=1 因为可以理解为不向背包中放入object时,也会有一种方案(就是空啦)
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<cmath>
#include<queue>
#include<stack>
#include<set>
#include<algorithm>
using namespace std;
#define maxNumber 52
int n;
int m;
int caseNumber=1;
int object[maxNumber];
unsigned long result[maxNumber][maxNumber];
int main()
{
while(cin>>n&&cin>>m&&n&&caseNumber<100){
for(int i=1;i<=n;i++){
cin>>object[i];
}
sort(object+1,object+n+1);
memset(result,0,sizeof(result));
for(int i =1;i<=n;i++)
//initial the array
result[i][0]=1;
//if start from n and choose just one object, result is 1
result[n][1]=1;
// i is the situation of start object
for(int i = n-1;i>=1;i--){
// j is the capicity
for(int j = 1; j<=n;j++){
//result[i+1][j-1] choose the object in i situation
result[i][j]=result[i+1][j-1];
int k;
for(k = i+1;k<=n;k++)
if(object[i]!=object[k])
break;
//result[k][j] doesn't choose object the same as that in i situation
result[i][j]+=result[k][j];
}
}
cout<<"Case "<<caseNumber<<":"<<endl;
while(m--){
int testCase;
cin>>testCase;
cout<<result[1][testCase]<<endl;
}
caseNumber++;
}
return 0;
}