您的位置:首页 > 其它

HDU 1500(经典的恶心DP)

2008-08-05 22:22 471 查看
这是比较经典的DP 有一点很明显 却很难肯定的

那就是在最好的分组方案中,每组中两根较短的筷子在有序筷子数列中一定是相邻的

dp[j][i]表示从前i根筷子中挑出j组(不考虑第三根)

dp[j][i]=min{

dp[j][i-1];(i>j*2)

dp[j-1][i-2]+(hash[i]-hash[i-1])^2;(n-i>(k-j)*3)

}

太恶心了 做得我很郁闷 代码贴上 备忘

#include <iostream>

#include <algorithm>

#include <functional>

using namespace std;

long hash[5010];

long dp[1010][5010];

int main()

{

long T,K,N;

scanf("%ld",&T);

while (T--)

{

scanf("%ld %ld",&K,&N);

long i,j;

for(i=0;i<N;++i)

{

scanf("%ld",&hash[i]);

}

sort(hash,hash+N,greater<long>());

long t=hash[1]-hash[2];

dp[0][2]=t*t;

for (i=3;i<N;++i)

{

t=hash[i]-hash[i-1];

t*=t;

dp[0][i]=dp[0][i-1]>t?t:dp[0][i-1];

}

for (i=1;i<K+8;++i)

{

long s=3*i+2;

t=hash[s]-hash[s-1];

t*=t;

dp[i][s]=dp[i-1][s-2]+t;

for (j=s+1;j<N;++j)

{

t=hash[j]-hash[j-1];

t*=t;

t=dp[i-1][j-2]+t;

dp[i][j]=dp[i][j-1]>t?t:dp[i][j-1];

}

}

printf("%ld\n",dp[K+7][N-1]);

}

return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: