I love sneakers!

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 4503 Accepted Submission(s):
1845

Problem Description
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
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.
 
Output
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.
 
Sample Input
5 10000 3
1 4 6
2 5 7
3 4 99
1 55 77
2 44 66
 
Sample Output
255
 
Source
 
 

分组背包问题,大意**要买鞋,有k种牌子,每种牌子至少买一双鞋子。每双鞋子有标价跟实际价值。求用m多的钱买最多价值的鞋。

其实我觉得这题的难点就在处理“至少”这点上面。

状态方程很多都能推出用 dp[k][m] 来表示 已经买了k种鞋 在有m钱状态下的 鞋的最大价值。

状态转移方程为

for( k = 1 ; k <= K ; k++)
        {
            for( i = 0 ; i < num[k] ; i++)
            {
                for( j = mm ; j >= m[k][i].m ; j--)
                {
                    if(dp[k][j - m[k][i].m] != -1)
                        dp[k][j] = Max(dp[k][j] , dp[k][j - m[k][i].m] + m[k][i].v);
                    if(dp[k-1][j - m[k][i].m] != -1 )
                        dp[k][j] = Max(dp[k][j] , dp[k-1][j - m[k][i].m] + m[k][i].v);

}
            }
        }

如果忽略了两个红色的判断句,大家都看得出这只是单纯的01背包且 没有条件限制,加了这两句就能实现至少了。理由如下

一开始我将dp[][]数组初始化为-1表示所有的数都不合法。大于0表示合法

然后将所有的 k = 0 dp[0][]置为0,这是为了 k = 1时能合法计算。

从状态方程中看出,当上一个状态值为-1时表示他不合法。所以当前状态没有计算的必要也不合法答案。

如果计算完第k类商品的取值后,所有的dp[k][]均为-1的时候,第k类表明没有一鞋被买。故所有状态都不合法,接下来的所有值也都将不合法。

在计算第k组商品的过程中,当某个-1变成一个非负数的时候,也就表明当前的第k种已经拿了第i件物品,所以变成合法答案了。

如此推下去,最后一个值dp[k][m],就是答案了。如果依然是-1,就输出impossible把。

5 13 3
1 2 3
1 4 6
2 10 2
3 2 2
3 1 2

7

m   k=0   k=1   k=2   k=3 
0    0    -1    -1    -1 
1    0    -1    -1    -1
2    0    3    -1    -1
3    0    3    -1    -1
4    0    6    -1    -1
5    0    6    -1    -1
6    0    9    -1    -1
7    0    9    -1    -1
8    0    9    -1    -1
9    0    9    -1    -1
10   0    9    -1    -1
11   0    9    -1    -1
12   0    9    5     -1
13   0    9    5      7

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
using namespace std;
struct node{
int w;
int v;
}que[][];
int num[];
int dp[][];
int main(){
int n,m,kk;
while(scanf("%d%d%d",&n,&m,&kk)!=EOF){
memset(num,,sizeof(num));
memset(dp,-,sizeof(dp));
for(int i=;i<=n;i++){
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
que[x][num[x]].w=y;
que[x][num[x]].v=z;
num[x]++;
}
for(int i=;i<=m;i++)
dp[][i]=;
for(int i=;i<=kk;i++){
for(int k=;k<num[i];k++){
for(int j=m;j>=que[i][k].w;j--){
if(dp[i][j-que[i][k].w]!=-)
dp[i][j]=max(dp[i][j],dp[i][j-que[i][k].w]+que[i][k].v);
if(dp[i-][j-que[i][k].w]!=-)
dp[i][j]=max(dp[i][j],dp[i-][j-que[i][k].w]+que[i][k].v);
}
}
}
if(dp[kk][m]<)
printf("Impossible\n");
else
printf("%d\n",dp[kk][m]);
}
return ;
}
 
 
 
 
 

最新文章

  1. PHP SESSION机制,从存储到读取
  2. 使用gulp+browser-sync搭建前端项目自动化以及自动刷新
  3. 无题的题 &amp; 模拟退火...
  4. SVProgressHUD进度条蒙版
  5. weblogic 12c下jxls导出excel报错Could not initialize class org.apache.poi.xssf.usermodel.XSSFVMLDrawing
  6. Java设计模式-原型模式(Prototype)
  7. 通过驱动向打印机发送一段(ESC)控制指令
  8. java JDK8 学习笔记——第16章 整合数据库
  9. Poj3680 Intervals
  10. (经典)tcp粘包分析
  11. 开发人员应关注的20个jQuery网站/博客
  12. BZOJ 1029 建筑抢修
  13. Android(java)学习笔记232:Android进程间通讯(IPC)之AIDL
  14. 【Demo 0007】导航控制器
  15. 编译gRPC
  16. find命令--xargs--exec
  17. 真机调试iwatch
  18. 手把手教你整合SSM框架(基于课工厂+MyEclipse 2017 CI 10)
  19. windows 下 nginx 配置文件路径
  20. docker-ce-17.09 仓库的创建与使用

热门文章

  1. Java分享笔记:使用keySet方法获取Map集合中的元素
  2. Q&amp;A - Apache、Nginx与Tomcat的区别?
  3. 给树莓派Raspbian stretch版本修改软件源
  4. cacti和nagios监控web平台搭建
  5. html基础之遗忘篇
  6. Oracle常用傻瓜问题1000问
  7. 守护进程,进程安全,IPC进程间通讯,生产者消费者模型
  8. manjaro安装teamviewer实现远程连接
  9. C# 控件置于最顶层、最底层、隐藏、显示
  10. 前端各种mate积累