zoukankan      html  css  js  c++  java
  • poj3659pascal

    题目描述:

    (警卫看守)

    给一棵n个结点的树,要求选中最少的结点使得每个结点被自己或直接相联的结点覆盖

    树形DP

    很明显是一颗树,虽然没有跟结点,但可以随便拎起一个来开始DP

    状态表示f[i,0..2];

    f[i,0]表示该结点可以被儿子看到的最优解

    f[i,1]表示该结点自己放置一个装置来进行覆盖

    f[i,2]表示该结点可以被父亲看到的最优解

    需要注意的是,f[i,0],f[i,2]都是可以被看到的最优解,而不是说只能被儿子或父亲看到的最优解

    那么方程即为

    f[i,0]:=min(f[soni,0],f[soni,1]);  //不完全

    f[i,1]:=min(f[soni,0],f[soni,1],f[soni,2]);

    f[i,2]:=min(f[soni,0],f[soni,1]);

    其中f[i,0]若全部儿子都取f[soni,0]那就不成立了,所以需要特别处理

    还有一些细节

    1.第23行只能是小于号不能取等号,因为相等的时候归到下一类应该更优

    2.叶子结点f[i,0]需要赋成极大值,影响的是f[fatheri,2],即它父亲的2状态,如果不赋初值,

    也就是f[fatheri,2]是0的话即表示用覆盖fatheri这个结点,它以及其子树所需最小费用为0,

    而这样的话相当于在fatheri的father处放置一个结点使得i也能被覆盖,其实是覆盖不到的

    而从DP本身考虑,f[i,0]当i是叶子时这个状态不存在,所以也不应该有

    3.输出时取min不能有f[1,2]因为该状态不存在,可能存在类似于第2条的问题

    View Code
     1 program sky;
    2 var
    3 x,y,i,n : longint;
    4 f : array[0..10001,0..2] of longint;
    5 a : array[0..10001,0..1000] of longint;
    6 v : array[0..10001] of boolean;
    7 function min(qq,ww: longint ):longint;
    8 begin
    9 if qq>ww then exit(ww) ; exit(qq);
    10 end;
    11 procedure dp(x : longint);
    12 var
    13 i,mini : longint;
    14 vv : boolean;
    15 begin
    16 vv:=false; mini:=maxlongint>>1;
    17 f[x,1]:=1;
    18 for i:=1 to a[x,0] do
    19 if not v[a[x,i]] then
    20 begin
    21 v[a[x,i]]:=true;
    22 dp(a[x,i]);
    23 if f[a[x,i],0]<f[a[x,i],1] then
    24 begin
    25 inc(f[x,0],f[a[x,i],0]);
    26 mini:=min(mini,f[a[x,i],1]-f[a[x,i],0]);
    27 end else
    28 begin
    29 inc(f[x,0],f[a[x,i],1]);
    30 vv:=true;
    31 end;
    32 inc(f[x,1],min(min(f[a[x,i],0],f[a[x,i],1]),f[a[x,i],2]));
    33 inc(f[x,2],min(f[a[x,i],0],f[a[x,i],1]));
    34 end;
    35 if (not vv) then inc(f[x,0],mini);
    36 end;
    37 begin
    38 assign(input,'tiaoshi.in'); reset(input);
    39 read(n);
    40 for i:=1 to n-1 do
    41 begin
    42 read(x,y);
    43 inc(a[x,0]); a[x,a[x,0]]:=y;
    44 inc(a[y,0]); a[y,a[y,0]]:=x;
    45 end;
    46 v[1]:=true;
    47 dp(1);
    48 writeln(min(f[1,0],f[1,1]));
    49 end.

    总结起来,树形dp的定义状态方式一般f[i,xx]都表示以i结点为根的子树的最优解

    skysun原创,装载请注明出处 http://www.cnblogs.com/skysun

  • 相关阅读:
    Java版本及历史简述
    ASCII、Unicode、UTF-8、UTF-16、GBK、GB2312、ANSI等编码方式简析
    同步(Synchronous)和异步(Asynchronous)方法的区别
    例10-12 *uva1637(概率dp)
    例10-11 uva11181
    例10-10 uva10491(简单概率)
    例10-9 uva1636简单概率问题
    全排列hash-康拓展开
    10-8 uva1262密码
    例10-6 uva1635(唯一分解定理)
  • 原文地址:https://www.cnblogs.com/skysun/p/2400758.html
Copyright © 2011-2022 走看看