zoukankan      html  css  js  c++  java
  • HDU4003 Find Metal Mineral 树形DP

      题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4003

      状态转移方程还是很好想的:f[i][j]表示第 i 个节点放 j 个机器人的最优解,f[i][j]=Min{ f[i][j] , f[i][j-k] + f[v][k] + (k?k:2)*e[i].w } 。

      写这个树形DP的时候,暴露了我以前没有仔细考虑的问题,导致状态转移的时候删删改改了很久。、

      1.仔细考虑转移方程初始化的问题,要根据求Min或者Max以及容量是否恰好来确定。

      2.在分组背包转移时,f[i][j]是前几组的最优值。

     1 //STATUS:C++_AC_256MS_1084KB
     2 #include<stdio.h>
     3 #include<stdlib.h>
     4 #include<string.h>
     5 #include<math.h>
     6 #include<iostream>
     7 #include<string>
     8 #include<algorithm>
     9 #include<vector>
    10 #include<queue>
    11 #include<stack>
    12 #include<map>
    13 using namespace std;
    14 #define LL __int64
    15 #define pii pair<int,int>
    16 #define Max(a,b) ((a)>(b)?(a):(b))
    17 #define Min(a,b) ((a)<(b)?(a):(b))
    18 #define mem(a,b) memset(a,b,sizeof(a))
    19 #define lson l,mid,rt<<1
    20 #define rson mid+1,r,rt<<1|1
    21 const int N=10010,INF=0x3f3f3f3f,MOD=10000,STA=8000010;
    22 const double DNF=1e13;
    23 
    24 struct Node{
    25     int u,v,w;
    26 }e[N*2];
    27 
    28 int first[N],next[N*2],vis[N],f[N][11];
    29 int n,s,k,mt;
    30 
    31 void adde(int a,int b,int c)
    32 {
    33     e[mt].u=a;e[mt].v=b;
    34     e[mt].w=c;
    35     next[mt]=first[a];first[a]=mt++;
    36     e[mt].u=b;e[mt].v=a;
    37     e[mt].w=c;
    38     next[mt]=first[b];first[b]=mt++;
    39 }
    40 
    41 void dfs(int u)
    42 {
    43     int i,j,v,q;
    44     i=first[u];
    45     vis[u]=1;
    46     if((next[i]==-1 || i==-1) && u!=s){
    47         f[u][0]=f[u][1]=0;
    48         return;
    49     }
    50     f[u][0]=0;
    51     for(;i!=-1;i=next[i]){
    52         v=e[i].v;
    53         if(vis[v])continue;
    54         dfs(v); 
    55         for(j=k;j>=1;j--){
    56             f[u][j]+=f[v][0]+2*e[i].w;
    57             for(q=1;q<=j;q++)
    58                 f[u][j]=Min(f[u][j],f[u][j-q]+f[v][q]+q*e[i].w);
    59         }
    60         f[u][0]+=f[v][0]+2*e[i].w;
    61     }
    62 }
    63 
    64 int main()
    65 {
    66  //   freopen("in.txt","r",stdin);
    67     int i,x,y,w;
    68     while(~scanf("%d%d%d",&n,&s,&k))
    69     {
    70         mt=0;
    71         mem(vis,0);
    72         mem(f,0);
    73         mem(first,-1);
    74         for(i=1;i<n;i++){
    75             scanf("%d%d%d",&x,&y,&w);
    76             adde(x,y,w);
    77         }
    78 
    79         dfs(s);
    80 
    81         printf("%d\n",f[s][k]);
    82     }
    83     return 0;
    84 }
  • 相关阅读:
    关于String
    MySQL中count(1)、count(*) 与 count(列名) 的执行区别?
    OSC的原理
    [java] 模拟QPS
    [java] 简单的ConcurrentHashMap
    [java] 线程池
    [Guava] EventBus
    [jvm]垃圾回收算法
    [zookeeper] Zookeeper概述
    [NS2]TCL语言基本语法
  • 原文地址:https://www.cnblogs.com/zhsl/p/3011048.html
Copyright © 2011-2022 走看看