耗费了我一上午的时间来肝这个题
考虑令
表示第i个点花费了k的价值能提供j个道具用来合成的最大价值。。。
然后发现
式子很容易推出来,但是发现这个复杂度嘛,不敢恭维
左思右想也优化不了,然后去看了题解,,,发现真的是这个玄学的复杂度…
但是需要加优化,就是令
表示第
个点最多合成多少个,显然这个可以根据儿子或者其本身的价值推出来
c++代码如下:
#include<bits/stdc++.h>
#define rep(i,x,y) for(register int i = x ; i <= y; ++ i)
#define repd(i,x,y) for(register int i = x ; i >= y; -- i)
using namespace std;
template<typename T>inline bool chkmax(T&x,T y) { return x < y ? x = y ,1 : 0; }
template<typename T>inline bool chkmin(T&x,T y) { return x > y ? x = y ,1 : 0; }
template<typename T>inline void read(T&x)
{
x = 0;char c;int sign = 1;
do { c = getchar(); if(c == '-') sign = -1; } while(!isdigit(c));
do { x = x * 10 + c - '0'; c = getchar(); } while(isdigit(c));
x *= sign;
}
const int N = 55,inf = 1e8 +7;
int nxt[N*N],to[N*N],w[N*N],head[N],tot;
inline void add(int x,int y,int val)
{
w[tot] = val;
nxt[tot] = head[x];
to[tot] = y;
head[x] = tot ++ ;
}
int f[N][101][2020],t[101][2020];
int n,m,c[N],d[N],p[N],mx[N];
bool rt[N];
void dfs(int x)
{
if(head[x] == -1)
{
rep(i,0,mx[x]) rep(j,0,m)
{
f[x][i][j] = p[x] * (min(d[x],j/c[x]) - i);
if(f[x][i][j] < 0) f[x][i][j] = -inf;
}
return ;
}
mx[x] = 100;
for(register int ii = head[x];~ii;ii = nxt[ii])
{
dfs(to[ii]);
c[x] += c[to[ii]] * w[ii];
if(x !=0)chkmin(mx[x],mx[to[ii]]/w[ii]);
}
if(x == 0) mx[x] = 0;
else chkmin(mx[x],m / c[x]);
for(register int ii = head[x];~ii;ii=nxt[ii])
{
int y = to[ii],val = w[ii];
rep(i,0,mx[x]) rep(j,0,m) t[i][j] = -inf;
rep(i,0,mx[x]) {if(i * val > mx[y]) continue;
repd(j,m,0) repd(k,j,0)
{
chkmax(t[i][j],f[y][i*val][j - k] + f[x][i][k]);
if(t[i][j] < 0) t[i][j] = -inf;
}}
rep(i,0,mx[x]) rep(j,0,m) f[x][i][j] = t[i][j];
}
repd(i,mx[x]-1,0) rep(j,0,m)
chkmax(f[x][i][j] ,f[x][i + 1][j] + p[x]);
}
char op[2];
int main()
{
memset(head,-1,sizeof head);
read(n); read(m);
rep(i,1,n)
{
read(p[i]); scanf("%s",op);
if(op[0] == 'A')
{
int c;
read(c);
rep(j,1,c)
{
int x,y;
read(x), read(y);
add(i,x,y);
rt[x] = 1;
}
}
else read(c[i]), read(d[i]),mx[i] = min(d[i],m/c[i]);
}
rep(i,1,n) if(!rt[i]) add(0,i,0);
dfs(0);
cout << f[0][0][m];
return 0;
}