POJ1285 Combinations, Once Again(背包 排列组合)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ1285 Combinations, Once Again(背包 排列组合)相关的知识,希望对你有一定的参考价值。

背包解组合数学问题,n种物品,每种num[i]个,求取r个的方法数。

背包思想,f[j]表示当前取j个数的方法数,则状态转移方程为

 

f[j] += f[k](max(j - num[i], 0) <= k < j)

外层循环枚举物品,内层循环从大到小枚举空间,最内层枚举方法数。

 

#include<cstdio>

#include<iostream>
#include<cstdlib>
#include<cstring>
#include<string>
#include<algorithm>
#include<map>
#include<queue>
using namespace std;

typedef long long LL;
const int N = 1000;
int num[N], que[N], n, m;
LL f[N];
int main(){
    freopen("1285.txt""r", stdin);
    int cas = 0;
    while(~scanf("%d %d", &n, &m ) && n){
        memset(num, 0sizeof(num));
        int tp;
        for(int i  = 0; i < n ;i++){
            scanf("%d", &tp);
            tp--;
            num[tp]++;
        }
        for(int i = 0; i < m; i++){
            scanf("%d", &que[i]);
        }
        memset(f, 0sizeof(f));
        for(int i  = 0 ;i <= num[0]; i++){
            f[i] = 1;
        }
        for(int i = 1; i < n; i++){
            for(int j = n; j >= 1; j--){
                for(int k = max(j - num[i], 0);  k < j ; k ++){
                        f[j] += f[k];
                }
            }
        }
        cas++;
        printf("Case %d:\n", cas);
        for(int i = 0; i < m; i++){
            printf("%I64d\n", f[que[i]]);
        }
    }
    return 0;
}

 

以上是关于POJ1285 Combinations, Once Again(背包 排列组合)的主要内容,如果未能解决你的问题,请参考以下文章

devIL ilLoad 错误 1285

51Nod--1285-山峰和分段

杭电 1285 确定比赛名次(拓扑排序)

HDU 1285 确定比赛名次

HDU 1285 确定比赛名次

HDU 1285 确定比赛名次