HDU 1500(经典的恶心DP)

这是比较经典的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;
}

   

posted @ 2008-08-05 22:22  Hdu-Lost  阅读(756)  评论(0编辑  收藏  举报