After months of hard working, Iserlohn finally wins awesome amount of scholarship. As a great zealot of sneakers, he decides to spend all his money on them in a sneaker store.
There are several brands of sneakers that Iserlohn wants to collect, such as Air Jordan and Nike Pro. And each brand has released various products. For the reason that Iserlohn is definitely a sneaker-mania, he desires to buy at least one product for each brand.
Although the fixed price of each product has been labeled, Iserlohn sets values for each of them based on his own tendency. With handsome but limited money, he wants to maximize the total value of the shoes he is going to buy. Obviously, as a collector, he won’t buy the same product twice.
Now, Iserlohn needs you to help him find the best solution of his problem, which means to maximize the total value of the products he can buy.
Input contains multiple test cases. Each test case begins with three integers 1<=N<=100 representing the total number of products, 1 <= M<= 10000 the money Iserlohn gets, and 1<=K<=10 representing the sneaker brands. The following N lines each represents a product with three positive integers 1<=a<=k, b and c, 0<=b,c<100000, meaning the brand’s number it belongs, the labeled price, and the value of this product. Process to End Of File.
For each test case, print an integer which is the maximum total value of the sneakers that Iserlohn purchases. Print "Impossible" if Iserlohn's demands can’t be satisfied.
5 10000 3 1 4 6 2 5 7 3 4 99 1 55 77 2 44 66
255
開始寫始終WA,初始化有問題。。。看題解才發現原來選擇的順序也有講究,又長見識了。
題意:一些鞋子有k種品牌,第k種牌子的鞋子裏面有一些品種不一樣的鞋子,每種都有本身的價格和價值,收藏家有m元想收集每種品牌的鞋子至少一雙(可是相同品牌相同品種的鞋他只要一雙),問他總共能夠收集多少價值的鞋子。
分析:有k個品牌,分組揹包問題,《揹包九講》是每組最多選一件,這裏不一樣,是選至少一件,咱們對每組
進行01揹包就好了.咱們當前選第k組的時候在裏面選擇物品的時候是選的第幾件.若是咱們當前是選第k組中的第一件,那麼是從第k-1組推過來的,若是不是取第一件(i),
那麼就是第k組中的前一件(i-1)推過來的.
如下內容就是這題的精(da)華(keng)了:
可是這裏有個很是重要的問題,咱們寫成要寫成以下形式兩個if不能調轉:
if(dp[k][v-price[i]] != -1)
dp[k][v] = max(dp[k][v] , dp[k][v - price[i]] + value[i]);
if(dp[k-1][v-price[i]] != -1 )
dp[k][v] = max(dp[k][v] , dp[k-1][v-price[i]] + value[i]);
解釋:
順序不能調轉,由於若是代價爲0,調轉的話,有可能出現先有dp[k][v] = dp[k-1][v-0]+v,再有dp[k][v] =dp[k][v-0]+v = dp[k-1][v-0]+v+v,因此物品取了兩次.
固然一種方便的解決辦法是直接寫個函數 a = max(a,b,c);
還有個重要的地方是初始化:
若是咱們一開始把dp初始化爲0,則當全部鞋子的價值都是0時,咱們就沒法區分是買不全那幾款鞋子仍是能買全但最大價值是0
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#define N 10005
using namespace std;
int dp[105][N]; ///dp[k][i] 表明在前k組中花費i取得的最大價值
int a[105],price[105],value[105];
int main()
{
int n,m,K;
while(scanf("%d%d%d",&n,&m,&K)!=EOF)
{
for(int i=1; i<=n; i++)
{
scanf("%d%d%d",&a[i],&price[i],&value[i]);
}
memset(dp,-1,sizeof(dp)); ///-1表示狀態不合法
for(int i=0; i<=m; i++) dp[0][i]=0;
for(int k=1; k<=K; k++)
{
for(int i=1; i<=n; i++)
{
if(a[i]==k)
for(int v=m; v>=price[i]; v--)
{
if(dp[k][v-price[i]] != -1)
dp[k][v] = max(dp[k][v] , dp[k][v - price[i]] + value[i]);
if(dp[k-1][v-price[i]] != -1 )
dp[k][v] = max(dp[k][v] , dp[k-1][v-price[i]] + value[i]);
}
}
}
if(dp[K][m]==-1) printf("Impossible\n");
else printf("%d\n",dp[K][m]);
}
return 0;
}