问题 H: Umbrellas for Cows-----------------------------思维(dp)

173 篇文章 0 订阅
53 篇文章 0 订阅

题目描述
Today is a rainy day! Farmer John’s N (1 <= N <= 5,000) cows, numbered 1…N, are not particularly fond of getting wet. The cows are standing in roofless stalls arranged on a number line. The stalls span X-coordinates
from 1 to M (1 <= M <= 100,000). Cow i stands at a stall on coordinate X_i (1 <= X_i <= M). No two cows share stalls.

In order to protect the cows from the rain, Farmer John wants to buy them umbrellas. An umbrella that spans coordinates X_i to X_j (X_i <= X_j) has a width of X_j - X_i + 1. It costs C_W (1 <= C_W <= 1,000,000) to buy an
umbrella of width W. Larger umbrellas do not necessarily cost more than smaller umbrellas.

Help Farmer John find the minimum cost it takes to purchase a set of umbrellas that will protect every cow from the rain. Note that the set of umbrellas in an optimal solution might overlap to some extent.
输入

  • Line 1: Two space-separated integers: N and M.
  • Lines 2…N+1: Line i+1 contains a single integer: X_i.
  • Lines N+2…N+M+1: Line N+j+1 contains a single integer: C_j.
    输出
  • Line 1: A single integer that is the minimum cost needed to purchase umbrellas for all the cows.

样例输入 Copy
6 12
1
2
11
8
4
12
2
3
4
4
8
9
15
16
17
18
19
19
样例输出 Copy
9
提示
There are 12 stalls, and stalls 1, 2, 4, 8, 11, and 12 contain cows. An umbrella covering one stall costs 2, an umbrella covering two stalls costs 3, and so on.By purchasing a size 4 umbrella, a size 1 umbrella, and a size 2 umbrella,
it is possible to cover all the cows at a cost of 4+2+3=9:

题意:
在 X 数轴上有 M 个整数点,点的坐标分别是 1 至 M。有 N(1<= N<= 5000)只奶牛,编号为 1… N,第 i 只奶牛所在的整数点坐标是 Xi(1<= Xi <= M <= 100,000), 没有两头奶牛在相同的点上。现在正在下雨,为了保护奶牛,FJ 需要购买很多把雨伞,把所有的奶牛都遮住。如果一把雨伞能遮住坐标是 a 到坐标是 b 的这一段(a<=b),那么这把雨伞的宽度就是 b-a+1。现在我们给出购买宽度是 1 的雨伞的价格,购买宽度是 2 的雨伞的价格,…购买宽度是 M 的雨伞的价格。

这里特别需要注意:宽度更大的雨伞的价格不一定超过宽度较小的雨伞,这完全取决于读入数据。你的任务是帮助 FJ 找到购买雨伞最低的成本,使得这些雨伞能把所有的奶牛遮住,从而不淋雨。需要注意的是最佳的解决方案雨伞可能会重叠。

解析:
设f[i]表示为 前i头奶牛被雨伞所覆盖的最小价值

状态转移方程:f[i]=min(f[i],f[j-1]+cost[a[i]-a[j]+1])

但是还有一个问题就是长度增加了但是价格没有变化。所以我们预处理一下最小后缀值

for(int i=m-1;i>=1;i--)
{
		cost[i]=min(cost[i],cost[i+1]);
}

#include<bits/stdc++.h>
using namespace std;
const int N=50000,M=1e6+10;
int a[N],cost[M];
int f[N];
int n,m;
int main()
{
	scanf("%d %d",&n,&m);
	for(int i=1;i<=n;i++) cin>>a[i];
	for(int i=1;i<=m;i++) cin>>cost[i];
	for(int i=m-1;i>=1;i--)
	{
		cost[i]=min(cost[i],cost[i+1]);
	}
	sort(a+1,a+1+n);

	for(int i=1;i<=n;i++)
	{
		f[i]=0x3f3f3f3f;
		for(int j=i;j>=1;j--)
		{
			f[i]=min(f[i],f[j-1]+cost[a[i]-a[j]+1]);
		}
	}
	cout<<f[n]<<endl;
 } 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值