• 洛谷 P4362 [NOI2002]贪吃的九头龙


    https://www.luogu.org/problemnew/show/P4362

    首先有个很显然的dp:ans[i][j][k]表示i节点用j号头,i节点为根的子树中共有k个点用大头时i节点为根的子树内的最小答案

    可以发现复杂度不太对。。

    研究一下,可以发现:如果没有大头的限制,且有>=2个头,那么答案一定是0

    毕竟,只要把所有节点按深度分类,同一深度的用同一种头,深度相差1的任意两类用不同种头,那么答案就是0了

    也可以发现:有了大头的限制,且有>=3个头,那么确定每个节点是否用大头之后,一定可以确定一种方案(即确定所有不是大头的节点具体用哪个头),并保证任意两个不是大头的节点间不产生贡献(只要把所有不是大头的节点按深度分类就行了)

    那么,状态简化为:ans[i][j][k]表示i号节点是/否用大头(由k决定),i号节点为根的子树中有j个点用大头时,i号节点为根的子树中的最小答案

    可以做了。。如果有>=3个头,照上面的做dp;如果只有2个头,与>=3个头时的区别仅仅是任意两个不是大头的节点间一定产生贡献,稍微改一下就行

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<cstring>
     4 #include<vector>
     5 using namespace std;
     6 #define fi first
     7 #define se second
     8 #define mp make_pair
     9 #define pb push_back
    10 typedef long long ll;
    11 typedef unsigned long long ull;
    12 typedef pair<int,int> pii;
    13 struct E
    14 {
    15     int to,nxt,d;
    16 }e[610];
    17 int f1[310],ne;
    18 int n,m,K;
    19 int an[310][310][2];
    20 bool fl1;
    21 void dfs(int u,int fa)
    22 {
    23     int i,j,k,v,t1,t2;
    24     an[u][1][1]=an[u][0][0]=0;
    25     for(k=f1[u];k;k=e[k].nxt)
    26     {
    27         v=e[k].to;
    28         if(v!=fa)
    29         {
    30             dfs(v,u);
    31             for(i=K;i>=0;i--)
    32             {
    33                 t1=t2=0x3f3f3f3f;
    34                 for(j=0;j<=i;j++)
    35                 {
    36                     t1=min(t1,min(
    37                         an[v][j][0]+an[u][i-j][0]+e[k].d*fl1,
    38                         an[v][j][1]+an[u][i-j][0]));
    39                     t2=min(t2,min(
    40                         an[v][j][0]+an[u][i-j][1],
    41                         an[v][j][1]+an[u][i-j][1]+e[k].d));
    42                 }
    43                 an[u][i][0]=t1;
    44                 an[u][i][1]=t2;
    45             }
    46         }
    47     }
    48 }
    49 int main()
    50 {
    51     int i,a,b,c;
    52     memset(an,1,sizeof(an));
    53     scanf("%d%d%d",&n,&m,&K);
    54     if(n-K<m-1)
    55     {
    56         puts("-1");
    57         return 0;
    58     }
    59     for(i=1;i<n;i++)
    60     {
    61         scanf("%d%d%d",&a,&b,&c);
    62         e[++ne].to=b;e[ne].nxt=f1[a];f1[a]=ne;e[ne].d=c;
    63         e[++ne].to=a;e[ne].nxt=f1[b];f1[b]=ne;e[ne].d=c;
    64     }
    65     fl1=(m==2);
    66     dfs(1,0);
    67     printf("%d",an[1][K][1]);
    68     return 0;
    69 }
  • 相关阅读:
    Python爬虫 Urllib库的高级用法
    Python爬虫入门 Urllib库的基本使用
    Oracle wm_concat()函数
    linux cut命令详解
    linux sort命令详解(转)
    linux awk 命令详解
    linux sed命令详解
    Oracle 数据导入导出操作 (转)
    sqlldr用法
    Python os与sys模块解析
  • 原文地址:https://www.cnblogs.com/hehe54321/p/9614580.html
Copyright © 2020-2023  润新知