3288 - 竞赛

通过次数

0

提交次数

0

时间限制 : 1 秒 内存限制 : 128 MB

XX年XX月的某一天,阿狸到黑森林里去玩,不幸被野兽们抓了起来。去觐见动物王国的领袖——巨龙。
动物王国的动物们很不和谐,动不动就会来个决斗,而决斗所破坏掉的森林资源自然全部要国王掏腰包。巨龙知道狐狸是最聪明的【其实是狡猾】,他答应如果阿狸能安排动物们的挑战组合,就答应放了他。
     动物们的决斗很有规律,他们分为两个阵营,决斗开始时两个阵营的动物排成两个队,每个动物有一个破坏值,然后由阿狸来安排比赛,动物们会按照顺序分组进行PK,可以是单挑,群挑,或者是单挑群。具体规则如下:
从后往前,每次从A阵营选出连续k1(k1>0)个动物,他们的破坏值之和为S1,从B阵营选出连续k2(k2>0)个动物,他们的破坏值之和为S2,选出的这些动物将进行决斗,这次破坏导致森林的修整费用为 (S1-K1)*(S2-K2)。决斗直到两个队伍都为空时结束。结束之后,这些决斗的总修整费用就为每次PK修整费用的和。
阿狸的大脑一片空白,只能让你来完成任务救出阿狸。你需要做的就是使这次决斗的费用最小。

题目输入

第一行两个正整数L1,L2分别表示两阵营的人数;
第二行L1个正整数,描述A阵营每个人的破坏值。
第三行L2个正整数,描述B阵营每个人的破坏值。

题目输出

一个正整数表示森林的最小修整费用

输入/输出样例

输入格式

3 2
1 2 3
1 2

输出格式

2

C++解答

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
const int maxn=2010;
int n,m;
int a[maxn],b[maxn];
int f[maxn][maxn];
int m_min(int,int,int);
void dp();
int main()
{
	//freopen("contest.in","r",stdin);
	//freopen("contest.out","w",stdout);
	dp();
	return 0;
}
int m_min(int x,int y,int z)
{
	int temp=x;
	if(temp>y) temp=y;
	if(temp>z) temp=z;
	return temp;
}
void dp()
{
	cin>>n>>m;
	for(int i=1;i<=n;i++)
	{
		cin>>a[i];
		a[i]--;
	}
	for(int i=1;i<=m;i++)
	{
		cin>>b[i];
		b[i]--;
	}
	memset(f,0x7f,sizeof(f));
	f[n+1][m+1]=0;
	for(int i=n;i>0;i--)
		for(int j=m;j>0;j--)
			f[i][j]=m_min(f[i+1][j],f[i][j+1],f[i+1][j+1])+a[i]*b[j];
	cout<<f[1][1]<<endl;
}