zoukankan      html  css  js  c++  java
  • HDU1011 Starship Troopers(树上背包)

    有n个洞穴编号为1~n,洞穴间有通道,形成了一个n-1条边的树, 洞穴的入口即根节点是1。 每个洞穴有x只bugs,并有价值y的金子,全部消灭完一个洞穴的虫子,就可以获得这个洞穴的y个金子. 现在要派m个战士去找金子,从入口进入。每次只有消灭完当前洞穴的所有虫子,才可以选择进入下一个洞穴。 一个战士可以消灭20只虫子,如果要杀死x只虫子,那么要x/20向上取整即(x+19)/20个战士。 如果要获得某个洞穴的金子,必须留下足够杀死所有虫子的战士数量, 即(x+19)/20个战士,然后这些留下战士就不能再去其它洞穴 其他战士可以继续走去其它洞穴,可以选择分组去不同的洞穴。 战士只能往洞穴深处走,不能走回头路 问最多能获得多少金子?

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<vector>
    using namespace std;
    const int maxn=1010;
    int dp[maxn][maxn];
    int N,M;
    vector<int> g[maxn];
    int v[maxn];
    int val[maxn];
    void dfs (int u,int pre) {
        for (int i=v[u];i<=M;i++)
           dp[u][i]=val[u];
        for (int i=0;i<g[u].size();i++) {
            if (g[u][i]==pre) continue;
            dfs(g[u][i],u);
            for (int j=M;j>=v[u];j--) 
                for (int k=1;k<=j-v[u];k++)
                    dp[u][j]=max(dp[u][j],dp[u][j-k]+dp[g[u][i]][k]);
        }
    } 
    int main () {
        while (~scanf("%d%d",&N,&M)) {
            if (N==-1&&M==-1) break;
            memset(dp,0,sizeof(dp));
            for (int i=0;i<=N;i++) g[i].clear();
            for (int i=1;i<=N;i++) {
                scanf("%d%d",&v[i],&val[i]);
                v[i]=(v[i]/20)+(v[i]%20==0?0:1);
            }
            for (int i=1;i<N;i++) {
                int x,y;
                scanf("%d%d",&x,&y);
                g[x].push_back(y);
                g[y].push_back(x);
            }
            if (M==0) {
                printf("0
    ");
                continue;
            }
            dfs(1,-1);
            printf("%d
    ",dp[1][M]);
        }
    }
  • 相关阅读:
    Visual Studio 2008 菜单:工具+选项+文本编辑器+HTML+格式,选中“键入时插入属性值引号”
    itemarray的意思
    SQL技巧大全
    IIS调用com组件的权限问题
    网站快速备案法(1小时)
    ASP.NET 2.0中WEB应用程序的部署
    c#中MessageBox的使用
    推荐一款DataGridView的打印解决方案
    使用C#格式化字符串
    关于MSSQL导入导出时主键与约束丢失的问题解决
  • 原文地址:https://www.cnblogs.com/zhanglichen/p/12644051.html
Copyright © 2011-2022 走看看