(01背包)Buy the souvenirs (hdu 2126)

http://acm.hdu.edu.cn/showproblem.php?pid=2126

Buy the souvenirs

Time Limit: 10000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1904    Accepted Submission(s): 711

Problem Description

When the winter holiday comes, a lot of people will have a trip. Generally, there are a lot of souvenirs to sell, and sometimes the travelers will buy some ones with pleasure. Not only can they give the souvenirs to their friends and families as gifts, but also can the souvenirs leave them good recollections. All in all, the prices of souvenirs are not very dear, and the souvenirs are also very lovable and interesting. But the money the people have is under the control. They can’t buy a lot, but only a few. So after they admire all the souvenirs, they decide to buy some ones, and they have many combinations to select, but there are no two ones with the same kind in any combination. Now there is a blank written by the names and prices of the souvenirs, as a top coder all around the world, you should calculate how many selections you have, and any selection owns the most kinds of different souvenirs. For instance:

And you have only 7 RMB, this time you can select any combination with 3 kinds of souvenirs at most, so the selections of 3 kinds of souvenirs are ABC (6), ABD (7). But if you have 8 RMB, the selections with the most kinds of souvenirs are ABC (6), ABD (7), ACD (8), and if you have 10 RMB, there is only one selection with the most kinds of souvenirs to you: ABCD (10).

Input

For the first line, there is a T means the number cases, then T cases follow.
In each case, in the first line there are two integer n and m, n is the number of the souvenirs and m is the money you have. The second line contains n integers; each integer describes a kind of souvenir. 
All the numbers and results are in the range of 32-signed integer, and 0<=m<=500, 0<n<=30, t<=500, and the prices are all positive integers. There is a blank line between two cases.

Output

If you can buy some souvenirs, you should print the result with the same formation as “You have S selection(s) to buy with K kind(s) of souvenirs”, where the K means the most kinds of souvenirs you can buy, and S means the numbers of the combinations you can buy with the K kinds of souvenirs combination. But sometimes you can buy nothing, so you must print the result “Sorry, you can‘t buy anything.”

Sample Input

2
4 7
1 2 3 4

4 0
1 2 3 4

Sample Output

You have 2 selection(s) to buy with 3 kind(s) of souvenirs.
Sorry, you can‘t buy anything.

题目大意:

一共有 n 个纪念品, 现在你有 m 金币, 告诉你 n 个纪念品的价格, 问你最多可以买多少个纪念品(Max),买最多纪念品有多少个组合(sum)

思路:

dp[i][k][j] = dp[i-1][k][j] + dp[i-1][k-1][j-a[i]]

dp[i][k][j] 代表从前 i 个纪念品中选 k 个最大价值为 j 的组合数

降维

dp[k][j] = dp[k][j] + dp[k-1][j-a[i]]

dp[k][j] 代表选 k 个最大价值为 j 的组合数

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <vector>
#include <map>
#include <algorithm>
using namespace std;

const int N = 550;
const int INF = 0x3fffffff;
const long long MOD = 1000000007;
typedef long long LL;
#define met(a,b) (memset(a,b,sizeof(a)))

int a[40];
int dp[40][N];

/// dp[k][j] 代表选 k 个物品,其中价值为 j 的物品的组合数

int main()
{
    int T;
    scanf("%d", &T);
    while(T--)
    {
        int i, j, k, n, m, Max=0;

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

        met(a, 0);
        met(dp, 0);

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

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

                   dp[k][j] += dp[k-1][j-a[i]];
                   if(dp[k][j]&&(k>Max)) ///如果 dp[k][j] 有值并且 k>Max 更新Max
                     Max = k;
                }
            }
        }

        ///Max 代表从 n 个物品中最多可以选 Max 种物品
        ///sum 代表有选 Max 个物品的总组合数
        int sum = 0;
        for(i=0; i<=m; i++)
            sum += dp[Max][i];

        if(!Max)
            printf("Sorry, you can‘t buy anything.\n");
        else
            printf("You have %d selection(s) to buy with %d kind(s) of souvenirs.\n", sum, Max);
    }
    return 0;
}
时间: 2024-11-08 03:20:33

(01背包)Buy the souvenirs (hdu 2126)的相关文章

poj3211Washing Clothes(字符串处理+01背包) hdu1171Big Event in HDU(01背包)

题目链接: poj3211  hdu1171 这个题目比1711难处理的是字符串如何处理,所以我们要想办法,自然而然就要想到用结构体存储,所以最后将所有的衣服分组,然后将每组时间减半,看最多能装多少,最后求最大值,那么就很愉快的转化成了一个01背包问题了.... hdu1711是说两个得到的价值要尽可能的相等,所以还是把所有的价值分为两半,最后01背包,那么这个问题就得到了解决.. 题目: Washing Clothes Time Limit: 1000MS   Memory Limit: 13

(01背包)HDU - 2126 Buy the souvenirs

原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=2126 题意:给n个物品,和m块钱,输出最多物品个数和其方案数. 委屈:求出最多物品个数就是一个裸的01背包,但是同时求出方案数,难住了我. 想了半天,感觉可以一波dp求出来,但是又想不明白状态是怎么表示和转移的. 无奈就先写个dfs提交试一发,果断超时了. 最后无奈看了题解,只能说,01背包还是不会. 其实与其说01背包不会不如说动态规划不会,感觉好难. 感觉自己好lowbee啊.. 感觉碰到dp就

hdu 2126 Buy the souvenirs(记录总方案数的01背包)

Buy the souvenirs Time Limit: 10000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1662    Accepted Submission(s): 611 Problem Description When the winter holiday comes, a lot of people will have a trip. Genera

hdu 2126 Buy the souvenirs 买纪念品(01背包,略变形)

题意:给出一些纪念品的价格,先算出手上的钱最多能买多少种东西k,然后求手上的钱能买k种东西的方案数.也就是你想要买最多种东西,而最多种又有多少种组合可选择. 思路:01背包.显然要先算出手上的钱m最多能买多少种东西k,可以从价格最少的纪念品买起,看最多能买多少种,置为k.接下来按照常规01背包计算,需要记录下方案数和组成的物品数,看代码就会懂的. 1 #include <iostream> 2 #include <stdio.h> 3 #include <cstring>

hdoj 2126 Buy the souvenirs 【另类01背包】

题意:求最多购买的件数以及有几种方法. 一看到这题就想到了背包,因为求得是种类数,所以我们可以将件数看做价值,将价格看做重量,这就变成01背包了(dp),但是还要求有几种购买方案,那么再来一个背包(kind). 分析:有三种情况: 1>dp[j] < dp[j-s[i]]+1 那么对于这一种情况  方案背包的状态转移方程是kind[j] = kind[j-s[i]]?kind[j-s[i]]:1;(考虑到kind[j-s[i]] ==0的时候,这时候kind[j] = 1): 证明:为什么是k

HDU 2126 01背包(求方案数)

Buy the souvenirs Time Limit: 10000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1886    Accepted Submission(s): 699 Problem Description When the winter holiday comes, a lot of people will have a trip. Genera

HDU 2126 Buy the souvenirs

Buy the souvenirs Time Limit: 1000ms Memory Limit: 32768KB This problem will be judged on HDU. Original ID: 212664-bit integer IO format: %I64d      Java class name: Main When the winter holiday comes, a lot of people will have a trip. Generally, the

Buy the souvenirs (01背包,动归)

When the winter holiday comes, a lot of people will have a trip. Generally, there are a lot of souvenirs to sell, and sometimes the travelers will buy some ones with pleasure. Not only can they give the souvenirs to their friends and families as gift

(01背包加强) hdu 2126

Buy the souvenirs Time Limit: 10000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1351    Accepted Submission(s): 477 Problem Description When the winter holiday comes, a lot of people will have a trip. Genera