首页 > 代码库 > 微软2017年预科生计划在线编程笔试第二场 EL SUENO

微软2017年预科生计划在线编程笔试第二场 EL SUENO

树上背包。

简单的树形$dp$,计算出摧毁每一个节点所需的最小费用,背包即可。

#include<bits/stdc++.h>using namespace std;struct X{    int fa;    int in;    int ip;    int c;}s[2010];int dp[2010][20010];int cost[2010];int f[20010];vector<int>g[2010];int n,root,ans;void dfs(int x){    if(g[x].size()==0)    {        cost[x]=s[x].c;        return ;    }    for(int i=0;i<g[x].size();i++)    {        int to=g[x][i];        dfs(to);    }    for(int j=1;j<=s[x].in;j++) f[j]=dp[x][j]=0x7FFFFFFF;    for(int i=0;i<g[x].size();i++)    {        int A = cost[g[x][i]],B = s[g[x][i]].ip;        if(A==0x7FFFFFFF) continue;        for(int j=1;j<=s[x].in;j++) f[j]=0x7FFFFFFF;        for(int j=0;j<=s[x].in;j++)        {            if(dp[x][j]==0x7FFFFFFF) continue;            f[min(s[x].in,j+B)] = min(f[min(s[x].in,j+B)],dp[x][j] + A);        }        for(int j=0;j<=s[x].in;j++) dp[x][j] = min(dp[x][j],f[j]);    }    cost[x] = dp[x][s[x].in];    if(cost[x]!=0x7FFFFFFF) cost[x] = cost[x] + s[x].c;}int main(){    scanf("%d",&n);    for(int i=1;i<=n;i++)    {        scanf("%d%d%d%d",&s[i].fa,&s[i].in,&s[i].ip,&s[i].c);        if(s[i].fa==0) root=i;        g[s[i].fa].push_back(i);    }    ans=0x7FFFFFFF;    dfs(root);    ans=cost[root];    if(ans!=0x7FFFFFFF) printf("%d\n",ans);    else printf("-1\n");    return 0;}

 

微软2017年预科生计划在线编程笔试第二场 EL SUENO