1. 程式人生 > >洛谷 P1311 選擇客棧 解題報告

洛谷 P1311 選擇客棧 解題報告

pac esp cos ron i++ 選擇 for amp 格式

P1311 選擇客棧

題目描述

麗江河邊有 \(n\) 家很有特色的客棧,客棧按照其位置順序從 \(1\)\(n\) 編號。每家客棧都按照某一種色調進行裝飾(總共 \(k\) 種,用整數 \(0\) ~ \(k-1\) 表示),且每家客棧都設有一家咖啡店,每家咖啡店均有各自的最低消費。

兩位遊客一起去麗江旅遊,他們喜歡相同的色調,又想嘗試兩個不同的客棧,因此決定分別住在色調相同的兩家客棧中。晚上,他們打算選擇一家咖啡店喝咖啡,要求咖啡店位於兩人住的兩家客棧之間(包括他們住的客棧),且咖啡店的最低消費不超過 \(p\)

他們想知道總共有多少種選擇住宿的方案,保證晚上可以找到一家最低消費不超過 \(p\)

元的咖啡店小聚。

輸入輸出格式

輸入格式:

\(n+1\) 行。

第一行三個整數 \(n ,k ,p\) ,每兩個整數之間用一個空格隔開,分別表示客棧的個數,色調的數目和能接受的最低消費的最高值;

接下來的 \(n\) 行,第 \(i+1\) 行兩個整數,之間用一個空格隔開,分別表示 \(i\) 號客棧的裝飾色調和 \(i\) 號客棧的咖啡店的最低消費。

輸出格式:

一個整數,表示可選的住宿方案的總數。

數據範圍

對於 \(30\%\) 的數據,有 \(n ≤100\)

對於 \(50\%\) 的數據,有 \(n ≤1,000\)

對於 \(100\%\) 的數據,有 \(2 ≤n ≤200,000,0<k ≤50,0≤p ≤100\)

, \(0≤\) 最低消費 \(≤100\)


這是一道很神奇的題目,因為我在短短20分鐘錯了四次(考場必拍啊)

做完瞅了一下題解,發現做法非常之多。

我的想法是,先用vector把每種顏色搞出來,然後前綴和統計某個區間是否有咖啡

對每種顏色,我們考慮每一個相鄰兩點區間,這個區間對答案的貢獻即是區間左邊的點數 \(\times\) 區間右邊的點數

好的,它是錯的。因為重復統計了。

我們考慮刪去重復統計的,稍稍模擬一下即可發現,前一個合法的區間的左端點及其左邊的點不需要統計,好了,維護一個指針就行了


Code:

#include <cstdio>
#include <vector>
#define ll long long
using namespace std;
const int N=2000010;
const int M=10010;
ll ans;
int n,k,p,f[N];
vector <int> ctsc[M];
int main()
{
    scanf("%d%d%d",&n,&k,&p);
    for(int color,cost,i=1;i<=n;i++)
    {
        scanf("%d%d",&color,&cost);
        ctsc[color].push_back(i);
        f[i]=f[i-1]+(cost<=p);
    }
    for(int i=0;i<k;i++)
        for(int s=0,j=1;j<ctsc[i].size();j++)
            if(f[ctsc[i][j]]-f[ctsc[i][j-1]-1])
            {
                ans+=(ll)(j-s)*(ll)(ctsc[i].size()-j);
                s=j;
            }
    printf("%lld\n",ans);
    return 0;
}

2018.8.5

洛谷 P1311 選擇客棧 解題報告