ACM 350. 小吃店(揹包变形)

350. 小吃店

★☆   输入文件:food.in   输出文件:food.out   简单对比
时间限制:1 s   内存限制:256 MB

小吃店

【背景】

    小白终于决定了去小吃店的方案。来到小吃店的小白被琳琅满目的小吃看得直流口水。他对自己说:我一定要把钱全部用来买小吃!!但是小白最近在减肥,所以他不希望吃太多,他给自己又定了一个量,他希望正好达到这个量,不能多也不能少。假设每种最多买一份。

【问题描述】

    给出n个数对(ai,bi),每个数对都满足ai>=bi。要求在这n个数对中选出k对,使得ai1+ai2+ai3+……+aik=m且bi1+bi2+bi3+……+bik=w,k为任意数,有几种方案。

【输入文件】

第一行有三个整数n,m,w。
接下来n行每行二个整数ai,bi。

【输出文件】

方案总数。

【输入输出样例】

food.in
4 3 2
2 1
3 2
1 1
2 1
food.out
3

样例解释
{1,3}、{2}和{3,4} (这里的数字表示第几对)

【数据范围】

对于 30%数据, 0<=n<=10; 0<=m,w<=100
对于100%数据, 0<=n<=50; 0<=m,w<=2,500
对于 100%数据,0<=ai,bi<=100
保证运算和输出不会超过maxlongint

#include <iostream>
#include <cstdio>

using namespace std;

#define MAX_N 2501
#define INF -999999

int n,m,w;
int dp[MAX_N][MAX_N];
int a[MAX_N],b[MAX_N];

int main()
{
    freopen("food.in","r",stdin);
    freopen("food.out","w",stdout);

    scanf("%d%d%d",&n,&m,&w);

    for(int i=0;i<n;i++) scanf("%d%d",&a[i],&b[i]);

    for(int i=0;i<=m;i++)
    dp[0][0]=1;

    for(int i=0;i<n;i++)
    {
        for(int j=m;j>=a[i];j--)
        {
            for(int k=w;k>=b[i];k--)
            {
                dp[j][k]+=dp[j-a[i]][k-b[i]];
            }
        }
    }

    printf("%d\n",dp[m][w]);

    return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章