• POJ 1947 (树形DP+背包)


    题目链接http://poj.org/problem?id=1947

    题目大意:树中各点都由一条边连接。问要弄出个含有m个点的(子)树,至少需要截去多少条边。

    解题思路

    设dp[i][j]为i总根(注意是当前点为总根,不再考虑其父亲,这题是要在原来的树里面切出一个树),留下j个点截去的最少的边。

    首先dp[i][1]=子结点数量,即只留下根,要把所有与子节点的边给截掉。

    对于dp[i][2~m]:如果取子结点,则dp[i][j]=min(dp[i][j],dp[i][j-k]+dp[t][k]-1)

    这里的-1比较巧妙,用的是逆向思维。如果硬要把子树接上去的话,则就被截取边就得少一条,则-1。

    至于为什么是dp[i][j-k]+dp[t][k],这里理解成根与儿子共同分一个j,所以取和。

    最后的DP的结果比较难想:

    ans=min(dp[1][m],dp[2~n][m]+1)

    即如果以1为总根,则dp[1][m]就是结果。

    否则对于其它点,要使其为总根,则必须切断其与父亲的边,所以结果+1。

    #include "cstdio"
    #include "iostream"
    #include "cstring"
    using namespace std;
    #define maxn 155
    #define inf 0x3f3f3f3f
    int n,m,u,v,head[maxn],son[maxn],tol;
    int dp[maxn][maxn];
    struct Edge
    {
        int next,to;
    }e[maxn];
    void addedge(int u,int v)
    {
        e[tol].to=v;
        e[tol].next=head[u];
        head[u]=tol++;
    }
    int dfs(int root)
    {
        dp[root][1]=son[root];
        int i=root;
        for(int a=head[root];a!=-1;a=e[a].next)
        {
            int t=e[a].to;
            dfs(t);
            for(int j=m;j>=1;j--)
                for(int k=1;k<=j-1;k++)
                    dp[i][j]=min(dp[i][j],dp[i][j-k]+dp[t][k]-1);
        }
    }
    int main()
    {
        //freopen("in.txt","r",stdin);
        scanf("%d%d",&n,&m);
        memset(dp,0x3f,sizeof(dp));
        memset(head,-1,sizeof(head));
        for(int i=1;i<n;i++)
        {
            scanf("%d%d",&u,&v);
            son[u]++;
            addedge(u,v);
        }
        dfs(1);
        int ans=inf;
        for(int i=1;i<=n;i++)
        {
            if(i==1) ans=min(ans,dp[i][m]);
            else ans=min(dp[i][m]+1,ans);
        }
        printf("%d
    ",ans);
    }
    13544792 neopenx 1947 Accepted 252K 0MS C++ 1010B 2014-10-19 15:40:17
  • 相关阅读:
    65 JSP 有哪些内置对象?作用分别是什么?
    为什么 JSP 要被淘汰?
    64 JSP 和 servlet 有什么区别?
    63 深拷贝和浅拷贝区别是什么?
    62 如何实现对象克隆?
    马哥博客作业第二周
    马哥博客作业第一周
    02djangoMVC模型
    01Django实践
    了不起的gatsby.js_一个现代化开发网站的网站产生系统
  • 原文地址:https://www.cnblogs.com/neopenx/p/4035029.html
Copyright © 2020-2023  润新知