uva10271 - Chopsticks(巧妙动归)

开始的时候我也认为A,B,C,中只需要对A,B求解即可。。。

但是。。这样的话,最后的结果可能出现A,B,C,(B-C)^2最小或者(A-C)^2最小,而不是我们预想的(A-B)^2最小。

所以这种思路是错的。

我们应该先把每组筷子中最长的那根先给了。。。

所以必须满足条件i*3<=j.....这样就可以肯定,前面的没配对的筷子中有符合条件的长筷。。。

巧妙的思路:::在降序中求解+给出最长筷条件

状态:dp[i][j]表示前i个数中能凑成j对筷子的最小“badness”。

状态转移:dp[i][j] = min(dp[i-2][j-1]+(a[i]-a[i-1])*(a[i]-a[i-1]) , dp[i-1][j]);

代码如下:

#include 
#include 
#include 

using namespace std;

#define M 5005
#define N 1010
int k, n, t, a[M], dp[M][N];
int main ()
{
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d", &k, &n);
        for(int i = n; i >= 1; i--) scanf("%d",&a[i]);
        for(int i = 1; i <= n ;i++)
        for(int j = 1; j*3<=i && j <= k+8; j++)
        {
            dp[i][j] = dp[i-2][j-1]+(a[i]-a[i-1])*(a[i]-a[i-1]);
            if(j*3!=i) dp[i][j] = min(dp[i][j],dp[i-1][j]);
        }
        printf("%d\n",dp[n][k+8]);
    }
    return 0;
}

你可能感兴趣的:(uva)