zoukankan      html  css  js  c++  java
  • 贪吃的九头龙树形dp

    开始切树形dp。。。

    思路:

    经研究发现,当m大于3的时候,可以把m当成3来运算。

    先把多叉树转化成二叉树,方便寻找每个节点的儿子和兄弟。

    dp[i][j][k]: 以i节点为根节点的子树,有j个大头,节点i的状态为k,这时候的难受值。(k=0,1)当k=0时,代表小头吃这个节点,反之,大头吃。

    map[i][j]: 节点i到节点j的边长。

    dp[x][j][1]=min(dp[x][j][1],dp[y][k][1]+tmp[j-k][1]+map[x][y],dp[y][k][0]+tmp[j-k][1]);

    dp[x][j][0]=min(dp[x][j][0],dp[y][k][0]+tmp[j-k][0]+t               ,dp[y][k][1]+tmp[j-k][0]);

    tmp[i][j]: 在运算一个节点之前,已经运算过的节点形成的dp[x][i][j];

    t代表当一条边两边都是0时,所应该增加的难受值。



    #include<stdio.h>
    #include<string.h>
    #include<iostream>
    using namespace std;
    struct list
    {
    	int l;
    	int r;
    }node[1001];
    int n,m,need;
    int map[301][301];
    int min3(int a,int b,int c)
    {
    	if(a>b)a=b;
    	if(a>c)a=c;
    	return a;
    }
    void init()
    {
    	int i,a,b,c;
    	cin>>n>>m>>need;
    	for(i=1;i<=n;i++)
    	{
    		node[i].l=node[i].r=0;
    	}
    	for(i=0;i<n-1;i++)
    	{
    		cin>>a>>b>>c;
    		if(a>b)swap(a,b);
    		map[a][b]=c;
    		if(node[a].l==0)
    		{
    			node[a].l=b;
    		}
    		else
    		{
    			a=node[a].l;
    			while(node[a].r)
    			{
    				a=node[a].r;
    			}
    			node[a].r=b;
    		}
    	}
    }
    int sum[301];
    int dp[301][301][10];
    int tmp[301][10];
    void dfs(int x)
    {
    	dp[x][1][1]=0;
    	dp[x][0][0]=0;
    	int j,k;
    	sum[x]=1;
    	int i;
    	i=node[x].l;
    	while(i)
    	{
    		int y=i;
    		dfs(y);
    		int t;
    		t=0;
    		if(m==2)t=map[x][y];
    		sum[x]+=sum[y];
    		for(j=0;j<301;j++)
    		{
    			tmp[j][0]=dp[x][j][0];
    			tmp[j][1]=dp[x][j][1];
    		}
    		memset(dp[x],0x2f,sizeof(dp[x]));
    		for(j=sum[x];j>=0;j--)
    		{
    			for(k=j-1;k>=0;k--)dp[x][j][1]=min3(dp[x][j][1],dp[y][k][0]+tmp[j-k][1],dp[y][k][1]+tmp[j-k][1]+map[x][y]);
    			for(k=j;k>=0;k--) dp[x][j][0]=min3(dp[x][j][0],dp[y][k][1]+tmp[j-k][0],dp[y][k][0]+tmp[j-k][0]+t);
    		}
    		i=node[i].r;
    	}
    }
    int main()
    {
    	init();
    	if(n<m+need-1)
    	{
    		printf("-1\n");
    		return 0;
    	}
    	memset(dp,0x2f,sizeof(dp));
    	dfs(1);
    	cout<<dp[1][need][1];
    	return 0;
    }
    
    
    
    


  • 相关阅读:
    使用Apache Commons-email邮件客户端发邮件
    Jfinal开发代码碎片_导出报表_配置druid数据源_使用guava_获取当前操作系统_JDK版本_jfinal-utils_jfinal验证码
    Memcached缓存集群_创建多实例
    HttpClient取得自定义的状态码302,并获取Header中的参数Location
    对象序列化和反序列化
    【校园电子书城】测试及部署
    mysql导入txt文件
    【校园电子书城】部分代码及数据库设计
    【校园电子书城】需求分析
    Domain logic approaches
  • 原文地址:https://www.cnblogs.com/javawebsoa/p/3091500.html
Copyright © 2011-2022 走看看