UVa 10271 - Chopsticks

传送门

UVa 10271 - Chopsticks

题意

每人选三只筷子A、B、C,求使$(A - B)^2$的最小的和。

思路

$dp[i][j]$表示前$i$只筷子中选$j$双最小的和。
状态转移方程
\(dp[i][j] = min(dp[i - 2][j - 1] + (chops[i] - chops[i - 1]^2), dp[i - 1][j])\)

代码

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int MAXN = 5100;
const int INF = 0x3f3f3f3f;
 
int dp[MAXN][1100], chops[MAXN];
 
int GetValue(int i)
{
    int t =  chops[i - 1] - chops[i];
    return t * t;
}
 
int main()
{
    //freopen("input.txt", "r", stdin);
    int n, i, j, k, T;
    scanf("%d", &T);
    while (T--)
    {
        scanf("%d%d", &k, &n);
        k += 8;
        for (i = n; i >= 1; i--)
            scanf("%d", &chops[i]);
        for (i = 0; i <= n; i++)
        {
            dp[i][0] = 0;
            for (j = 1; j <= k; j++)
                dp[i][j] = INF;
        }
        for (i = 3; i <= n; i++)
            for (j = 1; j <= k; j++)
            {
                if (i >= j * 3 && dp[i - 2][j - 1] != INF)
                    dp[i][j] = min(dp[i - 1][j], dp[i - 2][j - 1] + GetValue(i));
            }
        printf("%d\n", dp[n][k]);
 
    }
    return 0;
}

Powered by Jekyll and Theme by solid