Codeforces #274 Div 1 簡要題解

比賽總結

打得有點慫,這次div1題目比較水,我做了三題,不過比較坑的是,我第二題因爲少了幾個特判,wa了8次才ac,第三題因爲看錯題,wa了兩次才ac
在正式和非正式選手裏排名438名
在正式選手裏排名306名
(做了三題,罰時太慘被一堆做2題的艹了。。。)

A. Exams

題目鏈接

http://codeforces.com/contest/480/problem/A

題目大意

某人要參加n 場考試,第i 場考試是在第ai 天考,也可以提前放到第bi 天考,但是提前考試的話,登分會標記這次考試是在第ai 天考的。考完一次考試登記一次考試時間。他希望登記冊裏,登記的時間是非降的,問最後一場考試最早能在什麼時候進行

思路

考試進行的順序,一定是按照ai 升序,即先考ai 小的,再考ai 大的。

但是每場考試是選ai 天考還是bi 天考呢?顯然是儘量選bi 天考,我們記錄last= 上一次考試的日期,若bi>=last ,就選bi 天考,否則就只能選ai 天考了。由於bi<ai ,而且之前預處理時,考試是按照ai 爲第一關鍵字升序,bi 爲第二關鍵字升序,所以ai 保證是大於等於last 的。這樣的做法是一定正確的

代碼

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>

#define MAXN 6000

using namespace std;

pair<int,int>pr[MAXN];
int n;

int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        scanf("%d%d",&pr[i].first,&pr[i].second);
    sort(pr+1,pr+n+1);
    int last=pr[1].second;
    for(int i=2;i<=n;i++)
    {
        if(pr[i].second>=last) last=pr[i].second;
        else last=pr[i].first;
    }
    printf("%d\n",last);
    return 0;
}

B. Long Jumps

題目鏈接

http://codeforces.com/contest/480/problem/B

題目大意

給你一個長度爲L 、有n 個刻度的尺子,第1號刻度是0,第n 號刻度是L ,給你每個刻度的位置,問最少要加多少個刻度,才能存在某兩個刻度之間距離爲x ,某兩個刻度之間距離爲y

思路

顯然,答案最多爲2,如果已經存在了某兩個刻度之間距離爲xy ,則答案爲1,如果已經存在了某兩個刻度之間距離爲xy ,則答案爲0
這個可以通過枚舉刻度a[i] ,然後二分判斷是否存在a[i]+xa[i]+y 來解決

但是重點不在於此,而是一個特殊情況:有可能存在某兩個已經存在的刻度,插入一個新的刻度後,就可以滿足題目要求了。這個就需要特判了,具體看代碼比較清楚吧

代碼

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>

#define MAXN 6000

using namespace std;

pair<int,int>pr[MAXN];
int n;

int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        scanf("%d%d",&pr[i].first,&pr[i].second);
    sort(pr+1,pr+n+1);
    int last=pr[1].second;
    for(int i=2;i<=n;i++)
    {
        if(pr[i].second>=last) last=pr[i].second;
        else last=pr[i].first;
    }
    printf("%d\n",last);
    return 0;
}

C. Riding in a Lift

題目鏈接

http://codeforces.com/contest/480/problem/C

題目大意

一個n 層摩天樓裏,某個人初始在a 層,每一步可以從一層x 走到另一層x ,但是有限制:|xx|<|xb|且不能停留在原樓層不動,問這個人走K 步,有多少種不同的走法

思路

一個非常顯然的DP思路:f[i][j]= 走完i 步後,這個人在第j 層的方案數。答案就是f[K][i]

dis=|xb|1 ,則f[i][j] 可以轉移到f[i+1][max{1,jdis}]f[i+1][min{n,j+dis}](f[i+1][j] 除外!)

這樣DP的複雜度爲O(n3) ,可以考慮通過優化貢獻答案的那部分來降維。

我們知道,給一個序列不斷進行區間加的操作,可以維護一個數組a[]a[] ,每次區間[L,R][L,R]valval 時,讓a[L]+=val ,a[R+1]+=val ,最後通過求前綴和即可得到若干次操作後的序列,這樣操作,每次是O(1) 的,就能在DP的區間更新答案步驟裏做到降維了,每次枚舉完某個i 的所有f[i][] 後,再通過求f[i][] 的前綴和來還原dp數組

代碼

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>

#define MAXN 6000

using namespace std;

pair<int,int>pr[MAXN];
int n;

int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        scanf("%d%d",&pr[i].first,&pr[i].second);
    sort(pr+1,pr+n+1);
    int last=pr[1].second;
    for(int i=2;i<=n;i++)
    {
        if(pr[i].second>=last) last=pr[i].second;
        else last=pr[i].first;
    }
    printf("%d\n",last);
    return 0;
}
發佈了378 篇原創文章 · 獲贊 10 · 訪問量 32萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章