問題 H: Umbrellas for Cows-----------------------------思維(dp)

題目描述
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;
 } 
發佈了430 篇原創文章 · 獲贊 8 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章