经典树形 dp,很早就想做了,但一直没有时间做(懒)。
做法其实我也早就知道了,但是代码打出来却总是 TLE,调了好久,越调越乱,最后重写一边就过了。???
#include <cstdio>
#include <cstring>
inline int max(const int& a, const int& b){
return a > b ? a : b;
}
inline int min(const int& a, const int& b){
return a < b ? a : b;
}
const int MAXN = 5e1 + 9, MAXM = 2e3 + 9, MAXC = 1e2 + 9;
struct Edge{
int to, next, dist;
}edge[MAXN * MAXN];
int cnt, head[MAXN];
inline void add(int from, int to, int dist){
edge[++cnt].to = to;
edge[cnt].dist = dist;
edge[cnt].next = head[from];
head[from] = cnt;
}
int power[MAXN], f[MAXN][MAXM][MAXC], dp[MAXM];
int n, m;
bool isleaf[MAXN], nottop[MAXN];
int price[MAXN], limit[MAXN];
int g[MAXN][MAXM];
void dfs(int node){
if(isleaf[node]){
for(int i = 0; i <= limit[node] && i * price[node] <= m; ++i)
for(int j = 0; j <= i; ++j)
f[node][i * price[node]][j] = power[node] * (i - j);
return;
}
limit[node] = 0x7fffffff;
for(int i = head[node]; i; i = edge[i].next)
dfs(edge[i].to), limit[node] = min(limit[node], limit[edge[i].to] / edge[i].dist);
for(int i = 0; i <= limit[node]; ++i){
cnt = 0;
std::memset(g, -0x3f3f3f3f, sizeof g);
g[0][0] = 0;
for(int j = head[node]; j; j = edge[j].next){
++cnt;
for(int k = 0; k <= m; ++k)
for(int l = 0; l <= k; ++l)
g[cnt][k] = max(g[cnt][k], g[cnt - 1][k - l] + f[edge[j].to][l][i * edge[j].dist]);
}
for(int j = 0; j <= m; ++j)
for(int k = 0; k <= i; ++k)
f[node][j][k] = max(f[node][j][k], g[cnt][j] + power[node] * (i - k));
}
}
int main(int argv, char *argc[]){
std::scanf("%d%d", &n, &m);
std::memset(f, -0x3f3f3f3f, sizeof f);
for(int i = 1; i <= n; ++i){
std::scanf("%d", power + i);
std::getchar();
if(std::getchar() == 'A'){
int c, type, num;
std::scanf("%d", &c);
for(int j = 1; j <= c; ++j){
std::scanf("%d%d", &type, &num);
add(i, type, num);
nottop[type] = true;
}
}
else{
isleaf[i] = true;
std::scanf("%d%d", price + i, limit + i);
}
}
for(int i = 1; i <= n; ++i)
if(!nottop[i]){
dfs(i);
for(int j = m; j >= 1; --j)
for(int k = 1; k <= j; ++k)
dp[j] = max(dp[j], dp[j - k] + f[i][k][0]);
}
int ans = 0;
for(int i = 1; i <= m; ++i)
ans = max(ans, dp[i]);
std::printf("%d\n", ans);
return 0;
}
原来我会不定期心情烦躁,代码混乱,想起一个变量就当场定义一个,想起一个函数就当场写一个,结果思路、代码都变成一团乱麻,还不如重写。以后一定要多想,少写。