zoukankan      html  css  js  c++  java
  • bzoj 1017 tree dp

    这道题几经波折啊。

    最开始和vfleaking一样,把题意理解错了,认为一个装备可能被多个装备依赖,然后想不出来,去看题解。

    发现自己理解错了题意,自己想想,其实也不难想到dp[i][j][k]表示“i号节点代表的子树,用掉j的钱,给父亲预留k个自己(但还是父亲付钱)”的状态,写出来交上去就是T,

    开始以为是常数问题,优化半天还是T,看了他人AC代码,才发现自己算法有一定问题:重复计算了很多东西。

    树形动规,一般在大的树规下,每个节点还会对儿子们来一次”资源分配“,一般是用背包解决,这道题也是这样,但又有一点不一样,就是我们也要给该子树的根节点本身分配资源,

    我就是这儿重复计算了,对于所有儿子的同一k,我算了多次。

      1 /**************************************************************
      2     Problem: 1017
      3     User: idy002
      4     Language: C++
      5     Result: Accepted
      6     Time:16524 ms
      7     Memory:48316 kb
      8 ****************************************************************/
      9  
     10 #include <cstdio>
     11 #include <cstring>
     12 #include <vector>
     13 #define max(a,b) ((a)>(b)?(a):(b))
     14 #define min(a,b) ((a)<(b)?(a):(b))
     15 #define maxn 55 
     16 #define maxm 2010
     17 #define maxl 110
     18 #define oo 0x3f3f3f3f
     19 using namespace std;
     20  
     21  
     22 int n, m;
     23 int indgr[maxn];
     24 int power[maxn], cost[maxn], limit[maxn];
     25 int head[maxn], next[maxn], dest[maxn], wght[maxn], tot;
     26  
     27 int dp[maxn][maxm][maxl];
     28 int ep[maxm];
     29  
     30 void insert( int a, int b, int w ) {
     31     tot++;
     32     wght[tot] = w;
     33     dest[tot] = b;
     34     next[tot] = head[a];
     35     head[a] = tot;
     36 }
     37 void dfs( int i ) {
     38     if( !head[i] ) return;
     39     cost[i] = 0;
     40     limit[i] = oo;
     41  
     42     for( int t=head[i]; t; t=next[t] ) {
     43         int s = dest[t], w = wght[t];
     44         dfs( s );
     45         cost[i] += cost[s]*w;
     46         limit[i] = min( limit[i], limit[s]/w );
     47     }
     48 }
     49  
     50  
     51 void dodp( int i ) {
     52     if( !head[i] ) {
     53         for( int l=0; l<=limit[i]; l++ )
     54             for( int k=l; k>=0; k-- ) {
     55                 int self = (l-k);
     56                 int j = self*cost[i];
     57                 if( j>m ) break;
     58                 dp[i][j][k] = self*power[i];
     59             }
     60         return;
     61     }
     62     for( int t=head[i]; t; t=next[t] )
     63         dodp( dest[t] );
     64     for( int l=0; l<=limit[i]; l++ ) {
     65         for( int j=0; j<=m; j++ ) ep[j]=0;
     66         for( int t=head[i]; t; t=next[t] ) {
     67             int v = dest[t], w = wght[t];
     68             int vl = l*w;
     69             for( int j=m; j>=0; j-- )
     70                 for( int jj=0; jj<=j; jj++ )
     71                     ep[j] = max( ep[j], ep[j-jj]+dp[v][jj][vl] );
     72         }
     73         for( int j=0; j<=m; j++ )
     74             for( int k=l; k>=0; k-- ) {
     75                 int self = l-k;
     76                 int remain =  j- self*cost[i];
     77                 if( remain<0 ) break;
     78                 dp[i][j][k] = max( dp[i][j][k], ep[remain]+self*power[i] );
     79             }
     80     }
     81 }
     82  
     83 int main() {
     84     scanf( "%d%d", &n, &m );
     85     for( int i=1; i<=n; i++ ) {
     86         char type[10];
     87         scanf( "%d%s", power+i, type );
     88         if( type[0]=='A' ) {
     89             int cnt;
     90             scanf( "%d", &cnt );
     91             for( int t=1,c,w; t<=cnt; t++ ) {
     92                 scanf( "%d%d", &c, &w );
     93                 insert( i, c, w );
     94                 indgr[c]++;
     95             }
     96         } else
     97             scanf( "%d%d", cost+i, limit+i );
     98     }
     99     int root = 0;
    100     for( int i=1; i<=n; i++ ) 
    101         if( indgr[i]==0 ) {
    102             root = i;
    103             break;
    104         }
    105     memset( dp, 129, sizeof(dp) );
    106     dfs(root);
    107     dodp(root);
    108     int ans = 0;
    109     for( int j=0; j<=m; j++ ) ans = max( ans, dp[root][j][0] );
    110     printf( "%d
    ", ans );
    111 }
    View Code
  • 相关阅读:
    Xcode 6 UITextField 键盘不弹出
    No Assistant Results
    iOS- 解决iOS10 App启动时放大铺满App Icon的问题
    iOS- 多线程中如何去保证线程安全
    iOS- 什么是GitHub?关于它的自我介绍「初识 GitHub」
    iOS- 利用AFNetworking3.0+(最新AFN)
    iOS- 利用AFNetworking3.0+(最新AFN)
    iOS- CALayer绘图,如何绘制渐变效果图
    iOS- Exception Type: 00000020:什么是看门狗机制
    iOS- Swift:指触即开,如何集成Touch ID指纹识别功能
  • 原文地址:https://www.cnblogs.com/idy002/p/4297034.html
Copyright © 2011-2022 走看看