紫书上的0-1背包例题,但是跟普通的0-1背包还是有些差别。
题意: 在告知的n首歌曲里,要选取一些歌曲 使得 歌曲数量尽量多,其次 唱的时间也要尽量长。
那么我们假定 i与j,和0-1背包类似,i代表前i首歌曲,j代表的是时间,是不是跟0-1背包里的第几个物品和重量类似呢,
那么0-1背包里 dp[i][j]代表的是前i个物品里,总共能承受的最大重量j内存放的最大重量。
那么这道题,dp[i][j]又代表什么呢?
很容易发现,他既要代表 歌曲的数目,又要代表选取歌曲的总长
那么我们就可以用一个结构体来表示
struct Nature
{
int number; //代表选取的歌曲数目
int totaltime; //代表选取的歌曲数目加起来的时间长度
bool operator < (const Nature & h)
{
return number<h.number || ( number==h.number && totaltime < h.totaltime) ;
}
//重载小于运算符,用来后面比较(因为首先要看歌曲数量,后面再看时间长度)
};
OK,状态定义好了,那么状态转移方程该如何写呢,通过简单的0-1背包我们很容易就能够推出
dp[i][j] = MAX ( dp[i-1][j], 选取这首歌之后的状态(数目+1 时间+t[i] ) )
然后就是代码了
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
struct