Chopsticks

38 篇文章 0 订阅

题意:有一个怪人吃饭喜欢用三根筷子,现在他想请他的朋友n个人+8(一定会有的家人亲戚),每个人也要分配3根筷子,现在给你n和筷子总数k,然后下一行是k根筷子的长度;现在要求A<=B<=C;求出总数(A - B ) ^ 2最小的值;

解析;转移方程:dp[ i ][ j ]  = min( dp[ i ] [ j - 1 ], dp[ i - 1 ] [ j - 2 ] + num[ j ] ,第一维代表人数,第二维代表筷子数,即第一个为第i个人现在选第C根筷子和第i - 1 个人选A,B,筷子(num[ j ] 的代价)

// Chopsticks.cpp : 定义控制台应用程序的入口点。
//

//#include "stdafx.h"
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<cmath>

using namespace std;
#define INF 999999999
const int maxn = 5005;
int num1[ maxn ], num2[ maxn ], dp[ 1005 ][ maxn ], n, k;

int cmp( int a, int b ){
	return a > b;
}

void Start(){
	cin >> n >> k;
	n += 8;
	for( int i = 1; i <= k; ++i )
		cin >> num1[ i ];
	sort( num1 + 1, num1 + k + 1, cmp);
	//for( int i = 1; i <= k; ++i )
	//	cout << "aaaaaaaa" << num1[ i ] << endl;
	memset( dp, 0, sizeof( dp ) );
	for( int i = 1; i <= n; ++i ){
		for( int j = 1; j <= k; ++j ){
			dp[ i ][ j ] = INF;
		}
	}
	for( int i = 1; i <= k; ++i ){
		num2[ i ] = ( num1[ i ] - num1[ i - 1 ] ) * ( num1[ i ] - num1[ i - 1 ] );
	}
}

//int _tmain(int argc, _TCHAR* argv[])
int main()
{
	int Case;
	cin >> Case;
	while( Case-- ){
		Start();
		for( int i = 1; i <= n; ++i ){
			for( int j = 3 * i; j <= k - ( n - i ) * 2; ++j ){
				dp[ i ][ j ] = min( dp[ i ][ j - 1 ], dp[ i - 1 ][ j - 2 ] + num2[ j ] );
			}
		}
		cout << dp[ n ][ k ] << endl;
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值