【题解】UVA10271:佳佳的筷子 Chopsticks

@luogu
贪心策略,如果知道当前一组筷子最小的那根,那么与他组合的肯定是与他相邻的,然后剩下那根最长的不用管
d p i , j dp_{i,j} dpi,j表示组了 j j j组筷子,最后一组最短的筷子是第 i i i根,倒着推导
d p i , j < − − − ( a i − a i + 1 ) 2 + d p i + 2 , j − 1 dp_{i,j}<---(a_i-a_{i+1})^2+dp_{i+2,j-1} dpi,j<(aiai+1)2+dpi+2,j1
这样其实转移意义不明,换言之会有漏掉,可以改变定义,当前用了 i − n i-n in这么多的筷子,最后一根筷子不一定是第 i i i
这样 d p i , j < − − − d p i + 1 , j dp_{i,j}<---dp_{i+1,j} dpi,j<dpi+1,j

Code:

#include <bits/stdc++.h>
#define maxn 5010
#define maxm 1010
using namespace std;
int a[maxn], dp[maxn][maxm], n, m;

inline int read(){
    
    
	int s = 0, w = 1;
	char c = getchar();
	for (; !isdigit(c); c = getchar()) if (c == '-') w = -1;
	for (; isdigit(c); c = getchar()) s = (s << 1) + (s << 3) + (c ^ 48);
	return s * w;
}

int main(){
    
    
	int Q = read();
	while (Q--){
    
    
		m = read() + 8, n = read();
		for (int i = 1; i <= n; ++i) a[i] = read();
		for (int i = 1; i <= n; ++i)
			for (int j = 1; j <= m; ++j) dp[i][j] = 1e9;
		for (int j = 1; j <= m; ++j)
			for (int i = n - 2; i; --i){
    
    
				dp[i][j] = dp[i + 1][j];
				if (n - i + 1 >= 3 * j)
					dp[i][j] = min(dp[i][j], dp[i + 2][j - 1] + (a[i] - a[i + 1]) * (a[i] - a[i + 1]));
			}
		printf("%d\n", dp[1][m]);
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/ModestCoder_/article/details/108630242