洛谷 P1311 選擇客棧(遞推,字首和)

2021-10-09 11:30:48 字數 1349 閱讀 9069

遞推,字首和

題目意思:

注意,題目要求的是,住宿方案的總數。 比如說,連個旅店 x, y,在 區間[x, y] 之間有 10 個 咖啡店滿足

消費 <= p, 但只算一種方案。

本題要點:

1、字首和:

sum[i] 表示前 i個客棧,咖啡消費小於等於p的數量。

2、用vector v[i] 來存顏色是 i 旅店的編號。 後面就可以按顏色分類計算,假設顏色是 i ,

假設現在已經處理完前k個旅店 也就是說 0, 1, …, k - 1 這幾個旅店已經計算完,它們之間可以配對的方案數量。

現在加入 a[k], 新增的 配對,只能是 k 和 0 ~ k - 1 這k個旅店之間的配對。

如果區間 [v[i][k], v[i][k - 1]](v[i][k] 表示 v[i] 裡 k座標的旅店編號), 裡面有消費 <= p 的旅店,顯然新增的 了配對數量就是 k 對。

如果區間 [v[i][k], v[i][k - 1]] 沒有有消費 <= p 的旅店, 那麼新增的配對,數量就是 k - 1 和 0 ~ k - 2 這 k - 1 個旅店之間的配對數量了。

3、用個變數,累加 每次新增的配對,得到的就是某種顏色的旅店的方案數。 所有顏色累加就是答案。

#include

#include

#include

#include

using

namespace std;

const

int maxn =

200010

, maxk =51;

int color[maxn]

, cost[maxn]

;int sum[maxn]

;// sum[i] 表示前 i個客棧,消費小於等於p的數量

int n, k, p;

vector<

int> v[maxk]

;void

solve()

else

}// printf("i = %d, len = %d, s = %d\n", i, len, s);

ans +

= s;

}printf

("%lld\n"

, ans);}

intmain()

else

sum[i]

= sum[i -1]

+ flag;

}solve()

;return0;

}/*5 2 3

0 5

1 3

0 2

1 4

1 5

*//*

3*/

題解 洛谷 P1311 選擇客棧(遞推)

方法一 暴力列舉第乙個客棧 第二個客棧以及兩個客棧之間的客棧,尋找合法的條件,答案 理論上也就30分吧,結果60分。貼一下 include include include includeusing namespace std const int maxn 200010 int a maxn p ma...

洛谷 P1311 選擇客棧

原題 首先暴力如果寫的優秀,可以拿到60分,這裡介紹兩種暴力 40 include include include include include using namespace std int color 200010 cost 200010 int main printf d n ans k r...

洛谷P1311 選擇客棧

做法1 樸素模擬。考慮到此題有可模擬性,所以我們可以列舉i,j,分別為第乙個人住i和第二個人住j的情況,然後再列舉k,k即為兩者中間的點,判斷是否有value p的情況就可以了。做法2 有技巧的運用一些與組合數有關的知識。考慮咖啡館的每個地方所代表的方案,發現我們可以從這裡突破。在讀入時把每乙個點如...