uva 10271(dp)

题意:从n个筷子中挑选n+8个三根筷子的集合,假如三根筷子按从小到大是a,b,c,那么让8+k个总(a-b)^2的值最小。

题解:用一个f[i][j]数组表示前j个筷子组成i个集合的总最小(a-b)^2值,所以dp思想就是f[i][j] = min{f[i][j - 1], f[i - 1][j - 2] + (cho[j] - cho[j - 1])^2},也就是不选cho[j]时,f[i][j]的值就是f[i][j - 1],如果选cho[j]时,也要选cho[j - 1],因为这两者组合的(a-b)^2的值会最小,那么f[i][j]就是f[i - 1][j - 2] + (cho[j] - cho[j - 1])^2。注意要cho数组是降序,因为这样做保证了一个筷子一旦被选为一个集合中的筷子c就不会再次被放到其他集合里了。

#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
const int N = 5005;
const int INF = 0x3f3f3f3f;
int t, k, n, cho[N];
int f[1005][N];

int main() {
	scanf("%d", &t);
	while (t--) {
		scanf("%d%d", &k, &n);
		for (int i = n; i >= 1; i--)
			scanf("%d", &cho[i]);
		k += 8;
		for (int i = 0; i < 1005; i++)
			for (int j = 0; j < N; j++)
				f[i][j] = INF;
		for (int i = 1; i <= n; i++)
			f[0][i] = 0;
		for (int i = 1; i <= k; i++) {
			for (int j = i * 3; j <= n; j++)
				f[i][j] = min(f[i][j - 1], f[i - 1][j - 2] + (cho[j] - cho[j - 1]) * (cho[j] - cho[j - 1]));
		}
		printf("%d\n", f[k][n]);
	}
	return 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值