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. 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.

Author

wangye

Source

HDU
2007-10 Programming Contest

Recommend

威士忌   |   We have carefully selected several similar
problems for you:  2128 2129 2130 2125 2124

记录方案总数的01背包,给dp数组加一维,记录方案总数,记住需要初始化,把所有 dp[i][1] 都设置成1。

题意:n个物品,m元钱,每个物品最多买一次,问最多可以买几件物品,并且输出方案数。加一维表示已经买几件物品。

附上代码:

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int main()
{
    int T,n,m,i,j;
    int a[35],dp[505][2];
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d",&n,&m);
        for(i=0; i<n; i++)
            scanf("%d",&a[i]);
        memset(dp,0,sizeof(dp));
        for(i=0; i<=m; i++) dp[i][1]=1;  //先全部标记为1,能拿这么多件物品,起码有一种方案
        for(i=0; i<n; i++)
            for(j=m; j>=a[i]; j--)
            {
                if(dp[j][0]==dp[j-a[i]][0]+1)   //如果记录了j元钱拿的物品数量,正好与此时记录的不拿这件物品的最多物品加1相等
                    dp[j][1]=dp[j-a[i]][1]+dp[j][1];
                else if(dp[j][0]<dp[j-a[i]][0]+1)  //如果小于,则更新dp
                {
                    dp[j][0]=dp[j-a[i]][0]+1;
                    dp[j][1]=dp[j-a[i]][1];
                }
            }
        if(dp[m][0]!=0)
            printf("You have %d selection(s) to buy with %d kind(s) of souvenirs.\n",dp[m][1],dp[m][0]);
        else
            printf("Sorry, you can‘t buy anything.\n");
    }
    return 0;
}
时间: 2024-08-02 22:51:31

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

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

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

(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 (动态规划)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2126 题意:给你n个物品,m元钱,问你最多能买个多少物品,并且有多少种解决方案. 一开始想到的是,先解决给m元钱因为我花的钱少就一定能购买够多的物品,因此是个贪心算法. 记买最多的物品数为c. 然后就是设计状态dp[i][j]代表我从前i个物品里花了j元钱,买c个物品有多少种方案. 后来发现状态维数不够,得重新想想. 于是就想到: 设计状态dp[i][j][k]代表我从前i个物品里买了j个,花的钱不

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

hdu 2126 Buy the souvenirs 【输出方案数】【01背包】(经典)

题目链接:https://vjudge.net/contest/103424#problem/K 题目大意: 给n个物品,和m块钱,输出能够购买最多物品的个数和购买这么多物品的方案数. #include <cstring> #include <iostream> #include <algorithm> #define clr(a) (memset(a,0,sizeof(a))) using namespace std; int dp[510][50], a[50];

hdu2126(求方案数的01背包)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2126 题意: n个物品,m元钱,每个物品最多买一次,问最多可以买几件物品,并且输出方案数. 分析:一看就想到01背包,不过得加一维来表示能买的物品件数.dp[i][j]表示在i元内至多能买j件物品.则状态转移方程为:dp[i][j]+=dp[i-a[k][j-1]. 最后把在1~m元内买到的最大件数mx加起来就是题目所求. #include <cstdio> #include <cstrin

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

P1417 烹调方案(思维+01背包)

(点击此处查看原题) 题意 有n种食材,每种食材有三个属性,ai,bi和ci,如果在t时刻完成第i样食材则得到ai-t*bi的美味指数,用第i件食材做饭要花去ci的时间.问在T时间内,什么样的烹调方案使得美味指数最大,输出最大的美味指数 解题思路 简单看来,这就是一个01背包问题,但是不同之处在于这里每个食材的价值会因为时间而改变,所以对于每个时间点,我们需要考虑此时先选择哪一种食材 记now为当前时间,食材1的属性:a1,b1,c1,食材2的属性:a2,b2,c2 1)先选择食材1的总价值:a

洛谷 P1064 金明的预算方案【DP/01背包-方案数】

题目背景 uim神犇拿到了uoi的ra(镭牌)后,立刻拉着基友小A到了一家--餐馆,很低端的那种. uim指着墙上的价目表(太低级了没有菜单),说:"随便点". 题目描述 不过uim由于买了一些辅(e)辅(ro)书,口袋里只剩M元(M<=10000). 餐馆虽低端,但是菜品种类不少,有N种(N<=100),第i种卖ai元(ai<=1000).由于是很低端的餐馆,所以每种菜只有一份. 小A奉行"不把钱吃光不罢休",所以他点单一定刚好吧uim身上所有钱