• [NOI2002]贪吃的九头龙


    XLVI.[NOI2002]贪吃的九头龙

    思路1.

    \(f[i][j][k]\)表示:在以\(i\)为根的子树上有\(j\)个点是归大头吃的,并且第\(i\)个点是归第\(k\)个头吃的。

    但这样做不仅复杂度高(似乎是\(O(n^5)\)?),还有个问题:无法保证每个头都至少吃了一个果子。

    思路2.

    \(f[i][j][0/1]\)表示:在以\(i\)为根的子树上有\(j\)个点是归大头吃的,并且第\(i\)个点 不是\((0)\)/是\((1)\)归大头吃的。

    \(m=2\)时,对于一条边来说,只有一边归大头吃而另一边归小头吃时才不会有损失。证明显然。

    否则,即\(m>2\),对于一条边来说,只有两边都归大头吃才会有损失。不归大头吃的地方,可以黑白染色直接造成没有任何地方有损失。

    答案为\(f[1][k][1]\)。复杂度\(O(n^3)\)

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    int n,m,p,head[310],cnt,f[310][310][2],g[310][2];
    struct node{
    	int to,next,val;
    }edge[610];
    void ae(int u,int v,int w){
    	edge[cnt].next=head[u],edge[cnt].to=v,edge[cnt].val=w,head[u]=cnt++;
    	edge[cnt].next=head[v],edge[cnt].to=u,edge[cnt].val=w,head[v]=cnt++;
    }
    void dfs(int x,int fa){
    	f[x][0][0]=f[x][1][1]=0;
    	for(int i=head[x],y;i!=-1;i=edge[i].next){
    		if((y=edge[i].to)==fa)continue;
    		dfs(y,x);
    		for(int j=0;j<=p;j++)for(int u=0;u<2;u++)g[j][u]=0x3f3f3f3f;
    		for(int j=0;j<=p;j++)for(int k=0;k<=j;k++)for(int u=0;u<=min(j-k,1);u++)for(int v=0;v<=min(k,1);v++)g[j][u]=min(g[j][u],f[x][j-k][u]+f[y][k][v]+edge[i].val*(m==2?!(u^v):(u&v)));
    		for(int j=0;j<=p;j++)for(int u=0;u<2;u++)f[x][j][u]=g[j][u];
    	}
    //	printf("%d:",x);for(int i=0;i<=p;i++)printf("(%d,%d)",f[x][i][0],f[x][i][1]);puts(""); 
    }
    int main(){
    	scanf("%d%d%d",&n,&m,&p),memset(head,-1,sizeof(head)),memset(f,0x3f3f3f3f,sizeof(f));
    	for(int i=1,x,y,z;i<n;i++)scanf("%d%d%d",&x,&y,&z),ae(x,y,z);
    	if(m+p-1>n){puts("-1");return 0;}
    	dfs(1,0);
    	printf("%d\n",f[1][p][1]);
    	return 0;
    }
    

  • 相关阅读:
    angular4 跨域携带cookie的设置
    引入第三方库jquery
    禁用输入框 浏览器的自动补全功能
    Mongodb 安装和启动
    chrome浏览器的表单自动填充
    jquery原生对象
    js获取文档高度
    字体在各个浏览器中的样式问题
    jquery中的ajax参数说明
    JavaScript中的面向对象
  • 原文地址:https://www.cnblogs.com/Troverld/p/14597307.html
Copyright © 2020-2023  润新知