记录编号 144633 评测结果 AAAAAAAAAA
题目名称 [JSOI 2008]魔兽地图 最终得分 100
用户昵称 GravatarAsm.Def 是否通过 通过
代码语言 C++ 运行时间 1.808 s
提交时间 2014-12-24 20:25:11 内存使用 82.94 MiB
显示代码纯文本
/*====================Asm.Def========================*/
#include <iostream>
#include <cctype>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <ctime>
#include <queue>
using namespace std;
inline void getd(int &x){
	char c = getchar();
	bool minus = 0;
	while(!isdigit(c) && c != '-')c = getchar();
	if(c == '-')minus = 1, c = getchar();
	x = c - '0';
	while(isdigit(c = getchar()))x = x * 10 + c - '0';
	if(minus)x = -x;
}
/*======================================================*/
const int maxn = 53, maxm = 2003, maxc = 102, INF = 0x7fffffff;
typedef long long LL;
struct Node{
	Node *son, *bro;
	int maxcost, maxcnt, cnt, pri, val;
	int f[maxc][maxm], S[maxc][maxm];
	void dfs();
	void dp();
}node[maxn], *Root;
int N, M, tmp[maxm];

void Node::dfs(){
	if(son == NULL){
		maxcnt = min(M / pri, maxcnt);
		if((LL)maxcnt * pri > M)maxcnt = 0, maxcost = 0;
		else maxcost = maxcnt * pri;
		return;
	}
	Node *it = son;
	maxcnt = INF;
	while(it != NULL){
		it->dfs();
		maxcost = min(M, maxcost + it->maxcost);
		if((LL)it->pri * it->cnt > M)
			pri = 0, maxcnt = 0;
		else{
			pri += it->pri * it->cnt;
			maxcnt = min(maxcnt, it->maxcnt / it->cnt);
		}
		it = it->bro;
	}
	if(pri)maxcnt = min(M / pri, maxcnt);
	else maxcnt = 0;
}

inline void init(){
	getd(N), getd(M);
	unsigned long long NotRoot = 1;
	int i, j, k, ch;
	for(i = 1;i <= N;++i){
		getd(node[i].val);
		while(!isalpha(ch = getchar()));
		if(ch == 'A'){
			getd(j);getd(k);
			getd(node[k].cnt);
			node[i].son = node + k;
			NotRoot |= (1ll << k);
			while(--j){
				getd(k);getd(node[k].cnt);
				node[k].bro = node[i].son;
				node[i].son = node + k;
				NotRoot |= (1ll << k);
			}
		}
		else
			getd(node[i].pri), getd(node[i].maxcnt);
	}
	NotRoot = (~NotRoot) & (NotRoot + 1);
	i = 0;
	while(NotRoot > 1)++i, NotRoot >>= 1;
	Root = node + i;
	Root->dfs();
}

inline void AddTo(int *S, int *f, int limS, int limf){
	int i, j;
	for(i = 1;i <= limS;++i){
		tmp[i] = 0;
		for(j = 0;j <= min(limf, i);++j)if(f[j] + S[i-j] > tmp[i])
			tmp[i] = f[j] + S[i-j];
	}
	for(i = 1;i <= limS;++i)S[i] = tmp[i];
}

void Node::dp(){
	int i, j;
	Node *it;
	if(son != NULL)for(it = son;it != NULL;it = it->bro){
		it->dp();
		for(i = 0;i <= maxcnt;++i)
			AddTo(S[i], it->f[i*it->cnt], maxcost, it->maxcost);
		for(j = 1;j <= maxcost;++j)
			f[maxcnt][j] = max(S[maxcnt][j], f[maxcnt][j-1]);
	}
	for(i = maxcnt-1;i >= 0;--i)for(j = 1;j <= maxcost;++j){
		f[i][j] = max(f[i][j-1], S[i][j]);
		if(j >= pri && f[i+1][j-pri] + val > f[i][j])
			f[i][j] = f[i+1][j-pri] + val;
	}
}

int main(){
	#if defined DEBUG
	freopen("test", "r", stdin);
	#else
	freopen("bzoj_1017.in", "r", stdin);
	freopen("bzoj_1017.out", "w", stdout);
	#endif
	init();
	
	Root->dp();
	printf("%d\n", Root->f[0][Root->maxcost]);
	
	#if defined DEBUG
	cout << endl << (double)clock()/CLOCKS_PER_SEC << endl;
	#endif
	return 0;
}