poj 1155 TELE(树型DP)

来源:互联网 发布:外汇的算法 编辑:程序博客网 时间:2024/05/22 11:46

        没有注意时间,已经写了三个小时了。

        好久时间没有做过背包问题,就找了一道练练手。再加上xcode用的还不是很熟练,硬是写了三个小时。

        题目的时限和空间放的很宽,我写的很丑陋的代码也A了。       

        题意:电视台要播放节目,一共有n个节点,其中有m个中转站,电视台连接不同节点需要消耗费用,叶节点是观众,观众会支付费用观看节目,问在不赔钱的前提下,电视台最多可以让多少观众看到节目。

        思路:很容易想到对于每个父节点dp[father][j]=Max(dp[father][j],dp[father][k]+dp[son][k],考虑到每个节点下的不同情况只能取一种,要防止重复取值,所以将状态转移公式修改为dp[father][k]=Max(dp[father][k],dp[last_son][k-j]+dp[son][j])。

        太久没做题,很多细节都没注意到。

#include<stdio.h>#include<string.h>#include<stdlib.h>const int N=3005;const int inf=0x3f3f3f3f;int dp[N][N],head[N],value[N];int cnt;int n,m;struct node{    int son;    int cost;    int next;}Edge[N];int Max(int x,int y){    if(x>y)        return x;    else        return y;}void AddEdge(int x,int y,int cost){    Edge[cnt].cost=cost;Edge[cnt].son=y;Edge[cnt].next=head[x];head[x]=cnt++;    return ;}void dfs(int father,int cost){    if(head[father]==-1)    {        dp[father][1]=value[father]-cost;        return ;    }    int last_son=0;    for(int i=1;i<=m;i++)        dp[last_son][i]=-inf;    for(int i=head[father];i!=-1;i=Edge[i].next)    {        int son=Edge[i].son;        dfs(son,Edge[i].cost);        for(int j=1;dp[son][j]!=-inf;j++)        {            for(int k=m;k>=j;k--)            {                if(dp[last_son][k-j]!=-inf)                {                    dp[father][k]=Max(dp[father][k],dp[last_son][k-j]+dp[son][j]);                }            }        }        if(Edge[i].next!=-1)        {            for(int j=1;j<=m;j++)            {                dp[son][j]=dp[father][j];            }        }        last_son=son;    }    for(int i=1;i<=m&&dp[father][i]!=-inf;i++)    {        dp[father][i]-=cost;    }    return ;}int main(){    while(scanf("%d%d",&n,&m)!=EOF)    {        cnt=1;        memset(head,-1,sizeof(head));        for(int i=1;i<=n-m;i++)        {            int k;            scanf("%d",&k);            for(int j=1;j<=k;j++)            {                int son,cost;                scanf("%d%d",&son,&cost);                AddEdge(i,son,cost);            }        }        for(int i=n-m+1;i<=n;i++)            scanf("%d",&value[i]);        for(int i=1;i<=n;i++)        {            for(int j=1;j<=n;j++)            {                dp[i][j]=-inf;            }        }        dfs(1,0);        for(int i=m;i>=0;i--)        {            if(dp[1][i]>=0)            {                printf("%d\n",i);                break;            }        }    }    return 0;}



0 0
原创粉丝点击