1. 程式人生 > >Luogu4438 HNOI/AHOI2018 道路 DP

Luogu4438 HNOI/AHOI2018 道路 DP

pac digi show const namespace ble stdin out pen

傳送門


這什麽鬼PJ組DP啊雖然一開始也沒想出來

\(f_{i,j,k}\)表示從首都走到\(i\),經過\(j\)條未翻修的公路和\(k\)條未翻修的鐵路的最小不便利值

隨便轉移就行了

#include<bits/stdc++.h>
//This code is written by Itst
using namespace std;

inline int read(){
   int a = 0;
   bool f = 0;
   char c = getchar();
   while(c != EOF && !isdigit(c)){
       if(c == ‘-‘)
           f = 1;
       c = getchar();
   }
   while(c != EOF && isdigit(c)){
       a = (a << 3) + (a << 1) + (c ^ ‘0‘);
       c = getchar();
   }
   return f ? -a : a;
}

const int MAXN = 20010;
long long dp[1010][41][41] , num[MAXN][3];
int ch[MAXN][2] , headSt , N;

void dfs(int now){
   ++headSt;
   if(now < 0){
       now = -now;
       for(int i = 0 ; i <= 40 ; ++i)
           for(int j = 0 ; j <= 40 ; ++j)
               dp[headSt][i][j] = (num[now][0] + i) * (num[now][1] + j) * num[now][2];
       return;
   }
   dfs(ch[now][0]);
   dfs(ch[now][1]);
   for(int i = 0 ; i < 40 ; ++i)
       for(int j = 0 ; j < 40 ; ++j)
           dp[headSt - 2][i][j] = min(dp[headSt - 1][i + 1][j] + dp[headSt][i][j] , dp[headSt - 1][i][j] + dp[headSt][i][j + 1]);
   headSt -= 2;
}

int main(){
#ifndef ONLINE_JUDGE
   freopen("4438.in" , "r" , stdin);
   //freopen("4438.out" , "w" , stdout);
#endif
   N = read();
   for(int i = 1 ; i < N ; i++){
       ch[i][0] = read();
       ch[i][1] = read();
   }
   for(int i = 1 ; i <= N ; i++){
       num[i][0] = read();
       num[i][1] = read();
       num[i][2] = read();
   }
   dfs(1);
   cout << dp[1][0][0];
   return 0;
}

Luogu4438 HNOI/AHOI2018 道路 DP