条件:
对于每件物品,选择这个物品,必须同时付出两种代价;对于每种代价,都给出一个限定值(背包容量)。要求:
怎样选择物品,可以获得最大的价值.
《背包九讲》上给出了公式
刚开始不懂i,v,u以及f[i][v][u]里面到底存什么值,到最后经过 飘牛 的精心指导,终于有了点头绪,下标与限定的两个量有关,也就是背包容量,感谢 飘飘
顺便做了一个题:
题目:HDU 2159 FATE
地址:请猛击
#include <cmath>
#include <ctime>
#include <cstdio>
#include <string>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define N 105
#define inf 0xffffff
using namespace std;
int dp[N][N] , ans , m , s ;
void CompletePack_2D( int m , int s , int a , int b ){ //m忍耐 k杀怪数 a 经验 b忍耐度
for( int i = b ; i <= m ; i++ )
for( int j = 1 ; j <= s ; j++ )
dp[i][j] = max ( dp[i][j] , dp[i-b][j-1] + a ) ;
}
void FindAns( int n ){
for( int i = 0 ; i <= m ; i++ )
for( int j = 0 ; j <= s ; j++ ){
if( dp[i][j] >= n && ans < m-i )
ans = m-i ;
}
}
int main() {
int n,k,a,b,i,j;
while( ~ scanf("%d%d%d%d",&n,&m,&k,&s) ) {//n经验 m忍耐 k怪物数 s 杀怪数
memset( dp , 0 , sizeof(dp) ) ;
for( i = 0 ; i < k ; i++ ){
scanf( "%d%d" , &a , &b ) ;
CompletePack_2D( m , s , a , b ) ; //m忍耐 k怪物数 a 经验 b忍耐度
}
ans = -1 ;
FindAns(n);
printf( "%d\n" , ans ) ;
}
return 0;
}
题目: HDU3496Watch The Movie
地址: 请猛击
代码:
#include <cmath>
#include <cstdio>
#include <string>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define maxn 1005
using namespace std;
int dp[maxn][maxn] , N , M , L ;
void OneZeroPack_2D( int a , int b ){ //L 时间限制 M 件数限制 a 时间 b价值
for( int i = M ; i >= 1 ; i-- )
for( int j = L ; j >= a ; j-- )
if( dp[i-1][j-a] != -1)
dp[i][j] = max ( dp[i][j] , dp[i-1][j-a] + b ) ;
}
int main( ) {
int cases , i , a , b ;
scanf( "%d" , &cases ) ;
while( cases-- ) {
scanf( "%d%d%d" , &N , &M , &L ) ;
memset( dp , -1 , sizeof(dp) ) ;
for( i = 0 ; i <= L ; i++ )
dp[0][i] = 0 ;
for( i = 0 ; i < N ; i++ ){
scanf( "%d%d" , &a , &b ) ;
OneZeroPack_2D( a , b ) ; // a 时间 b价值
}
int m = dp[M][L] ;
if( m == -1 )
m = 0 ;
printf( "%d\n" , m ) ;
}
return 0;
}
小开心,(*^__^*) 嘻嘻……