bzoj 4457: 游戏任务

4457: 游戏任务

Time Limit: 10 Sec  Memory Limit: 64 MB
Submit: 128  Solved: 71
[Submit][Status][Discuss]

Description

你正在玩一个名叫Age Of Cities的游戏。由于迫切需要升级你的城市,而且因为你太笨了,只知道做任务可以增加经验值,所以你决定去做游戏任务。你使用了一种顶尖的黑客技术得到了整个游戏的任务描述,发现这个游戏的任务可以分成主任务和附属任务两种,而你只有在完成主任务后才能解锁该主任务下的附属任务。你快速估计了一下你完成每个任务所需要的时间,并了解了完成这个任务可以增加的经验值,而经验值正是你升级所必须的。然而留给你的时间不长了,因为你的暑假只剩下 个小时了,而暑假过后你打算要好好学习,再也不会玩游戏了。所以你希望能够在这有限的 小时内获得最大的经验值。你整理出了做每个任务需要的时间 和做每个任务能够获得的经验值 ( 的单位为小时且保证 和 都是整数),然而你并不关心应该做什么样的任务,你只关心自己能得到的最大的经验值是多少。(我们假设你能够一天24小时不睡觉不吃饭不上厕所,全部用来玩游戏)
 

Input

输入的第一行是两个整数n,T,表示主任务的数目以及剩余的时间;
接下来的输入描述了这n个主任务。对于每个主任务,第一行为三个整数n_i,t_i0,c_i0,表示第i个主任务下有n_i个附属任务,且完成主任务所需的时间为t_i0,得到的经验值为c_i0;接下来n_i行,每行两个整数t_ij,c_ij,表示第i个主任务下的第j个附属任务所需的时间为t_ij,得到的经验值为c_ij。

Output

输出一行,包含一个整数,表示可以获得的经验值的最大值。

Sample Input

3 10
0 2 3
0 3 6
0 5 8

Sample Output

17

HINT

1≤n≤100,0≤n_i≤500,1≤t_ij,T≤500,1≤c_ij≤100,000

可以每个大任务单独背包,然后再和外面的大背包合并,共复杂度是 O(T*∑n_i + T^2*n)

前面一个的复杂度是每个大任务单独背包的,后面的是合并这个大任务和总背包。

#include<bits/stdc++.h>
#define ll long long
using namespace std;
int n,m,T,bag[505];
int N,f[505],V,W,v,w;

inline void dp(){
	memset(f,0,sizeof(f));
	scanf("%d%d%d",&N,&V,&W);
	for(int i=1,O;i<=N;i++){
		scanf("%d%d",&v,&w);
		O=V+v;
		for(int j=T;j>=O;j--) f[j]=max(f[j],f[j-v]+w);
	}
	for(int i=V;i<=T;i++) f[i]+=W;
}

inline void merge(){
	for(int i=T;i;i--)
	    for(int j=0;j<=i;j++) bag[i]=max(bag[i],bag[i-j]+f[j]);
}

int main(){
	scanf("%d%d",&n,&T);
	for(int i=1;i<=n;i++){
		dp();
		merge();
	}
	printf("%d",bag[T]);
	return 0;
}
原文地址:https://www.cnblogs.com/JYYHH/p/8610127.html