【2018/09/15测试T2】【SOJ 1805】切木板

【题目】

题目描述:

有一个 m\times n 的矩形木板。你需要把这个木板切成 1\times 1 的小方块,也就是竖着切 n-1 刀、横着切 m-1 刀。横着切第 i 个位置的权值为 x_{i} ,竖着切第 j 个位置的权值为 y_{j} 。切某一刀时的费用为切这一刀的权值乘上切过的块数。

请你安排切的顺序使得所有费用之和最小。

输入格式:

第一行两个数 mn 。
接下来一行 m-1 个整数 x_{1}x_{2},…,x_{m-1} 。
接下来一行 n-1 个整数 y_{1}y_{2},…,y_{n-1} 。

输出格式:

输出一个数,表示最小的费用之和 mod  10^{9}+7 。

样例数据:

输入

6 4
2 1 3 1 4
4 1 2

输出

42

备注:

【数据规模与约定】
对于 30% 的数据, m+n ≤ 10 。
对于 60% 的数据, m , n ≤ 500 。
对于 100% 的数据, 2 ≤ m,n ≤ 10^{6} ;0 ≤ x_{i},y_{j} ≤ 10^{9} 。

【提醒】
建议本题加读入优化。

 

【分析】

就是贪心+模拟吧,应该不是很难

 

【代码】

#include<cctype>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define N 1000005
#define mod 1000000007
using namespace std;
int Read()
{
	int x=0;
	char c=getchar();
	while(!isdigit(c))
	  c=getchar();
	while(isdigit(c))
	{
		x=(x<<1)+(x<<3)+(c^'0');
		c=getchar();
	}
	return x;
}
int x[N],y[N];
bool cmp(int a,int b)  {return a>b;}
int main()
{
//	freopen("cutboard.in","r",stdin);
//	freopen("cutboard.out","w",stdout);
	int m,n,i,j,ans=0;
	m=Read(),n=Read();
	//scanf("%d%d",&m,&n);
	for(i=1;i<m;++i)  x[i]=Read();     //scanf("%d",&x[i]);
	for(i=1;i<n;++i)  y[i]=Read();     //scanf("%d",&y[i]);
	sort(x+1,x+m,cmp),sort(y+1,y+n,cmp);
	i=1,j=1;
	while(i<m&&j<n)
	{
		if(x[i]>y[j])  ans=(ans+1ll*x[i++]*j)%mod;
		if(x[i]<=y[j])  ans=(ans+1ll*y[j++]*i)%mod;
	}
	while(i<m)  ans=(ans+1ll*x[i++]*n)%mod;
	while(j<n)  ans=(ans+1ll*y[j++]*m)%mod;
	printf("%d",ans);
//	fclose(stdin);
//	fclose(stdout);
	return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值