/************************************************************************/
/* 01背包 */
/************************************************************************/
/*
#include<stdio.h>
#include<stdlib.h>
int main() {
int n;
int j;
int _max;
int v;
int w;
int dp[ 10000 ] = { 0 };
scanf( "%d" , & n );
scanf( "%d" , & _max );
while( n -- ) {
scanf( "%d%d" , & w , & v );
for( j = _max ; j >= w ; j -- ) {
if( dp[ j ] < dp[ j - w ] + v ){
dp[ j ] = dp[ j - w ] + v;
}
}
}
printf( "%d\n" , dp[ _max ] );
return 0;
}
*/
/************************************************************************/
/* 两个限制条件的01背包问题 */
/************************************************************************/
//比如飞机要装货物,货物有体积和重量、价值三个属性,飞机有最大空间和最大载重限制
//那么具有空间和重量两个限制条件的背包问题,跟上面的类似,下面给出一个简化代码
/*
for( i = 0 ; i < num ; i ++ ) {
cin >> volume >> weight >> value;
for( j = Capacity ; j >= volume ; j -- ) {
for( k = Weight ; k >= weight ; k -- ) {
dp[j][k] = max( dp[j][k] , dp[j-volume][k-weight]+value);
}
}
}
*/
/************************************************************************/
/* 多重背包问题 每种背包可以有多个 */
/************************************************************************/
//题目描述
//输入第一行n和m,表示n元资金、m种大米
//之后有m行,每行有三个数p、h、c,分别代表每种大米的每袋价格,每袋重量,c代表该类大米的袋数
//输出n元资金可以购买到最多多少重量的大米
//大米是整袋卖的,钱可以不花完
//解题思路:每一种大米,有h袋,而这h袋极有可能是无法完全购买的,怎么办呢?就把这h袋大米拆分一下
//按照2的次幂进行拆分,即2^0 2^1 2^3 ....和一个余数,比如9可以拆分成1、2、4、2
//把这些拆分的结果当做是一件物品即可,即一件背包。这些被拆分的1、2、4、2可以组合成任何一个小于等于9的正整数
//这些新生成的背包,就可以认为是01背包了。
//这就是拆分的原因
/*
#include<stdio.h>
#include<stdlib.h>
int main() {
int n , m , p , h , c , i , j;
int dp[ 10000 ] = { 0 };
int cnt = 0;//用于记录被分的背包的个数
int price[ 1000 ];
int weight[ 1000 ];
scanf( "%d%d" , &n , &m );
while( m -- ) {
scanf( "%d%d%d" , &p , &h , &c );
//注意循环中变量的初始化
int t = 1;
while( t < c ) {
c = c - t;
price[ cnt ] = t * p;
weight[ cnt ++ ] = t * h;
t = t * 2;
}
price[ cnt ] = c * p;
weight[ cnt ++ ] = c * h;
}
for( i = 0 ; i < cnt ; i ++ ) {
for( j = n ; j >= price[ i ] ; j -- ) {
if( dp[ j ] < ( dp[ j - price[ i ] ] + weight[ i ] ) ) {
dp[ j ] = dp[ j - price[ i ] ] + weight[ i ];
}
}
}
printf( "%d\n" , dp[ n ] );
return 1;
}
*/
/*
8 2
2 100 4
4 100 2
*/
/************************************************************************/
/* 完全背包问题 每种背包游无限个 */
/************************************************************************/
//秋秋的减肥计划,题目描述:
//秋秋爱吃糖果,吃糖果能给她幸福感,但是吃糖又会增加她体内的卡路里
//她每天摄入的卡路里量是有限的,设为m,糖果有n种
//首先输入n
//然后n行,每行两个值,分别是某种糖果可以给秋秋带来的幸福感和增加的卡路里
//最后一行是m
/*
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int max( int x , int y ) {
return x > y ? x : y;
}
int a[1010], b[1010], f[100010], n, m;
int main () {
while(scanf("%d", &n) != EOF) {
int i , j;
int ans = 0;
for( i=1; i<=n; ++i) {
scanf("%d%d", &a[i], &b[i]);
}
scanf("%d", &m);
memset(f, 0x80, sizeof f);
f[0] = 0;
for( i=1; i<=n; ++i) {
for( j=b[i]; j<=m; ++j) {
f[j] = max(f[j], f[j - b[i]] + a[i]);
}
}
for(i=0; i<=m; ++i) ans = max(ans, f[i]);
printf("%d\n", ans);
}
return 0;
}
*/