【題目描述:】
麗江河邊有n 家很有特色的客棧,客棧按照其位置順序從 1 到n 編號。每家客棧都按照某一種色調進行裝飾(總共 k 種,用整數 0 ~ k-1 表示),且每家客棧都設有一家咖啡店,每家咖啡店均有各自的最低消費。
兩位遊客一起去麗江旅遊,他們喜歡相同的色調,又想嘗試兩個不同的客棧,因此決定分別住在色調相同的兩家客棧中。晚上,他們打算選擇一家咖啡店喝咖啡,要求咖啡店位於兩人住的兩家客棧之間(包括他們住的客棧),且咖啡店的最低消費不超過 p 。
他們想知道總共有多少種選擇住宿的方案,保證晚上可以找到一家最低消費不超過 p元的咖啡店小聚。
【輸入格式:】
輸入檔案hotel.in,共n+1 行。
第一行三個整數n ,k ,p,每兩個整數之間用乙個空格隔開,分別表示客棧的個數,色調的數目和能接受的最低消費的最高值;
接下來的n 行,第 i+1 行兩個整數,之間用乙個空格隔開,分別表示 i 號客棧的裝飾色調和i 號客棧的咖啡店的最低消費。
【輸出格式:】
輸出檔名為hotel.out 。
輸出只有一行,乙個整數,表示可選的住宿方案的總數。
輸入樣例#1: 5輸入輸出樣例2305
1302
1415
輸出樣例#1:
3
【演算法分析:】
正解是o(n)的複雜度,但2000000的資料nlog2n就能過(2023年的時候自然是過不了的)
發現k種顏色分別是從0~k-1排的,可以把o(n3)暴力列舉的複雜度優化一下:
開乙個二位陣列c,c[i][j]表示第i種顏色的第j個客棧是c[i][j]號
迴圈開三層,第一層列舉顏色
第二、三層迴圈反向列舉這個顏色的客棧
第二層表示右邊的客棧,第三層表示左邊的客棧,
若是這兩個客棧間的最小花費比p小(st表o(1)查詢),則從第乙個這個顏色的客棧開始一直到左邊的這個客棧,都可以和右邊的客棧匹配形成一組方案
時間複雜度在最壞的情況下應該比o(n2)要小
效率大大提公升.
而再深入一想,可以將「找到某個客棧的左邊最後乙個客棧,使得兩個客棧之間的最小花費小於等於p"這個操作利用二分來做
時間複雜度o(n log2 n)
但實測不如方法一優
【**:】
1 #include2 #include3 #include4using
namespace
std;56
const
int maxn = 200000 + 10;7
const
int k = 22;8
9int
n, k, p, ans;
10int t[maxn], c[51
][maxn], st[maxn][k], log2[maxn];
11struct
hotel h[maxn];
1415 inline int
read()
2223
int query(int l, int
r) 27
intmain()
34for(int i = 1; i <= n; i++)
35 c[h[i].color][++t[h[i].color]] =i;
3637
for(int j = 1; j <= k; j++)
41for(int i = 0; (1
<< i) <= n; i++)
42 log2[1
<< i] =i;
43for(int i = 1; i <= n; i++)
44if(!log2[i]) log2[i] = log2[i - 1
];45
46for(int i = 0; i < k; i++)
57//
pos = l - 1;
58for(int j = end - 1; j >= 1; j--) 63}
64 ans +=pos;65}
66}67 printf("
%d\n
", ans);
68 }
洛谷 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 有技巧的運用一些與組合數有關的知識。考慮咖啡館的每個地方所代表的方案,發現我們可以從這裡突破。在讀入時把每乙個點如...
洛谷P1311 選擇客棧
麗江河邊有n 家很有特色的客棧,客棧按照其位置順序從 1 到n 編號。每家客棧都按照某一種色調進行裝飾 總共 k 種,用整數 0 k 1 表示 且每家客棧都設有一家咖啡店,每家咖啡店均有各自的最低消費。兩位遊客一起去麗江旅遊,他們喜歡相同的色調,又想嘗試兩個不同的客棧,因此決定分別住在色調相同的兩家...