蜜汁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;
}








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