http://acm.hdu.edu.cn/showproblem.php?pid=5534
比赛的时候已经想到是背包了,并且是完全背包。搞了一下,发现如果单纯的这样,那么结果可能不是树,(存在好几个联通块)
于是呼,瞎搞了一个,限制了一下数量。。竟然tle了。。。
关键就是预处理。假设最开始的就是你。
然后其余的度数,分到这些点中,求和最大。。
这样dp就爽歪歪了。
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
const int maxn=2100;
int main()
{ int m;
int t;
int dp[2][maxn];
int dp2[maxn];
int a[maxn];
scanf("%d",&t);
while(t--){
scanf("%d",&m);
for(int i=0;i<m-1;i++){
scanf("%d",&a[i]);
if(i!=0)
a[i]-=a[0];
}
for(int i=0;i<=m-2;i++)
dp2[i]=-0x3f3f3f3f;
dp2[0]=a[0]*m;
for(int i=1;i<=m-2;i++){
for(int j=i;j<=m-2;j++)
//dp[i%2][j]=max(dp[(i-1)%2][j],dp[(i-1)%2][j-i]+a[j]);
dp2[j]=max(dp2[j],dp2[j-i]+a[i]);
}
printf("%d\n",dp2[m-2]);
}
return 0;
}