蜜汁dp


由於初中玩泥巴。到現在好像都不是很懂泛化揹包那一套理論,但是某位大爺教了我一個很迷的dfs序dp....

代碼還是非常簡單的。但是這裏的f[i][j]表示的卻是正在考慮i節點,已經用掉了j個節點。。。(這句話我也思考了很久,結論是這個正在考慮確實很玄妙,,,首先i號節點肯定是沒選,但是他又肯定是要值得去被考慮的。這句話還是看了代碼自己領悟吧。。鬼畜的dp狀態可以簡化一下本來分類討論到欲仙欲死的題目)

#include <cstdio> 
#include <cmath> 
#include <ctime> 
#include <string> 
#include <cstring> 
#include <cstdlib> 
#include <iostream> 
#include <algorithm> 
   
#include <vector> 
 
#define pb push_back
 
#define forup(i,a,b) for(int i=(a);i<=(b);i++) 
#define fordown(i,a,b) for(int i=(a);i>=(b);i--) 
   
#define maxn 3005
#define maxm 100005
#define INF 1070000000 
using namespace std; 
typedef long long ll; 
typedef unsigned long long ull; 
   
template<class T> inline 
void read(T& num){   num = 0; bool f = true;char ch = getchar();   while(ch < '0' || ch > '9') { if(ch == '-') f = false;ch = getchar();}  while(ch >= '0' && ch <= '9') {num = num * 10 + ch - '0';ch = getchar();}   num = f ? num: -num; }
int out[100];
template<class T> inline
void write(T x,char ch){  if (x==0) {putchar('0'); putchar(ch); return;} if (x<0) {putchar('-'); x=-x;}int num=0; while (x){ out[num++]=(x%10); x=x/10;} fordown(i,num-1,0) putchar(out[i]+'0'); putchar(ch); }
/*==================split line==================*/
int n,lim;
int cnt;
int chu[maxn];
int val[maxn];
int  que[maxn*10];
int f[maxn][maxn];
vector<int> g[maxn];
void  dfs(int x,int fa)
{  cnt++; que[cnt]=x;
 for(int i=0;i<g[x].size();i++)    {   int v=g[x][i];    if(v!=fa)  dfs(v,x);    }
      chu[x]=cnt;
 }
 
int main()
{  cin>>n>>lim;
  forup(i,1,n)   read(val[i]);
     forup(i,1,n-1){int x,y; read(x);read(y);g[x].pb(y);  g[y].pb(x);   }
     dfs(1,0);
     forup(i,0,n) forup(j,0,n)   f[i][j]=-INF;
     f[1][0]=0;
      
    forup(i,1,cnt)
    forup(j,0,lim)
    { 
     f[i+1][j+1]=max(f[i+1][j+1],f[i][j]+val[que[i]]);
      f[chu[que[i]]+1][j]=max(f[chu[que[i]]+1][j],f[i][j]);
    }
/*  forup(i,1,cnt+1)  cout<<que[i]<<' ';cout<<endl;
    forup(i,1,cnt)
    forup(j,1,lim)
    { cout<<"f["<<i<<"]["<<j<<"]="<<f[i][j]<<endl;
    }*/
    int cmax=-INF;
    forup(i,1,lim)  cmax=max(cmax,f[cnt+1][i]);
    cout<<cmax;
 
    return 0;
}








發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章