NOIP2015解題報告

2021-07-11 23:39:24 字數 4415 閱讀 1200

day1.

當時的zxn很弱,弱到連dfs都調不明白就開始去noip。

現在他會了dfs,二分答案,求lca,bfs,拓撲排序。

所以他回去填noip2015的題解坑。

t1.我現在依然不知道除了這種尾遞迴式的寫法之外還有啥別的寫法……

偽**:

void dfs(int i,int j,int x)

咳我好像現在明白了……

大概乙個迴圈確實能搞出來……

t2.

求最小環,當時zxn心裡確實也是這麼想的。

由於他太弱了不會dfs,所以他並不知道怎麼寫。

題解:

dfs一遍,記一下時間戳。

void dfs(int x)

然後後來仔細一想,嗯我還是bfs吧。

次奧……?t掉了qaq

嗯我們還是冷靜一下,發現……

如果是bfs,需要拓撲排序,刪掉沒有用的那些點,只剩下環即可。

#include

#include

#include

#include

#define rep(i,n) for(int i = 1; i <= n ; i ++)

#define repg(i,x) for(int i = head[x] ;~ i ; i = edge[i].next)

#define rep_d(i,n) for(int i = n ; i > 0 ; i --)

#define rep_0(i,n) for(int i = 0 ; i < n ; i ++)

#define rd(i,x,n) for(int i = x; i <= n ; i ++)

#define clr(a,b) memset(a,b,sizeof(a))

#define v edge[i].to

using namespace std;

intread()

int to[200005];

bool vis[200005],vis_now[200005];

intq[200005],tid[200005],tim = 0,ans = 1

<< 30,end[200005];

int main()

int h = 0,t = -1;

rep(i,n)

if(!end[i])vis[q[++ t] = i] = 1;

while(h <= t)

rep(i,n)}}

printf("%d\n",ans);

return

0;}

qaq當時明明知道標算然而就是寫不出來?

t3.

鬥地主。

張地主出的一道水題。張地主親口說道:「noip的一道水題。」

張地主這次ctsc還出了一道提交答案題。

「我們可以發現第8個點是個網格圖。」

「第九個點是除了前幾個調換了下順序之外的網格圖。」

「第十個點是挖掉了一些點的網格圖。」

whx:「我要吐槽!怎麼檢驗它是網格圖呢?」

「我的暴力spfa怎麼跑的這麼慢呢……?」

tat

題解:

暴力搜尋即可。

我們考慮對於當前的手牌,先列舉順子應該會優一點,因為這樣方便加最優性剪枝。

我們考慮:

if(ans <= depth )return;

加這個剪枝就過了。

#include

#include

#include

#include

#define rep(i,n) for(int i = 1; i <= n ; i ++)

#define repg(i,x) for(int i = head[x] ;~ i ; i = edge[i].next)

#define rep_d(i,n) for(int i = n ; i > 0 ; i --)

#define rep_0(i,n) for(int i = 0 ; i < n ; i ++)

#define rd(i,x,n) for(int i = x; i <= n ; i ++)

#define clr(a,b) memset(a,b,sizeof(a))

#define v edge[i].to

using namespace std;

int s[20];

int read()

int cases,n,ans;

void dfs(int now)

rep_0(i,13)

if(s[i] == 3)

ans = min(ans,a + b + c + now);

rep_0(i,8)

if(j == 12)j --;

while(j >= i)s[j --] ++;

}rep_0(i,10)

if(j == 12)j --;

while(j >= i)s[j --] += 2;

}rep_0(i,11)

if(j == 12)j --;

while(j >= i)s[j --] += 3;

}}int main()

dfs(0);

if(s[13] == 2)ans ++;

printf("%d\n",ans);

}return

0;}

#include

#include

#include

#include

#define rep(i,n) for(int i = 1; i <= n ; i ++)

#define rep_0(i,n) for(int i = 0 ; i < n ; i ++)

#define rd(i,x,n) for(int i = x; i <= n ; i ++)

#define clr(a,b) memset(a,b,sizeof(a))

#define v edge[i].to

using

namespace

std;

int read()

int n,m,l;

int dis[50005];

bool check(int x)

return1;}

int bin_ans(int l,int r)

int main()

t2.

zxn在乙個月前不可置信地問fsf:」這怎麼可能是一道特別簡單的dp?」

現在他看到這道題:」哦我自己真是智障。」

設f[i][j][k]表示a串到i,b串到j,一共搞了k個串連起來的方案數。 (a

[i]==

b[j]

anda

[i−1

]!=b

[j−1

])f[

i][j

][k]

=∑pf

[p][

j−1]

[k−1

] (a

[i]==

b[j]

anda

[i−1

]==b[

j−1]

)f[i

][j]

[k]=

∑pf[

p][j

−1][

k−1]

+f[i

−1][

j−1]

[k]

字首和 + 滾動陣列優化。

這就沒了啊qaq

t3.

zxn原來一直讀錯題了。

他讀成了使得所有的花費總和最小。

題解:使得最大的花費最小,顯然二分答案。

問題是怎麼check。

我們可以利用它的lca。

我們考慮這兩個點(u,v),如果dis(u,v) >ans,那是要擔責任的。

我們把u - > v的路徑都標一遍,表示它們用過一遍,並且我們把距離答案最大的差記為lim。

假設我們有p條邊要擔責任。

當有一條邊a它的邊權 >= lim,且有use[a] == p,那麼我們就可以刪掉它了。

總的複雜度我一開始以為這是個暴力,所以一直覺得自己不會做。

現在想想每次複雜度是可以優化成o(n)的啊qaq

考慮我們每次只標一下那兩個節點和它們的lca。

我們直接對它們到lca的路徑都加一下就好了,但是如果每乙個都單獨加的話顯然是不優的。

我們考慮其實這個玩意可以用dfs序優化一發,就是我們每次找葉子節點進行往上的遞推。

這樣就是o(n)的辣qaq

總複雜度是o(nl

og2n

) 所以zxn還是太弱了qaq

noip2015運輸計畫解題報告

公元 2044 年,人類進入了宇宙紀元。l 國有 n 個星球,還有 n 1 條雙向航道,每條航道建立在兩個星球之間,這 n 1 條航道連通了 l 國的所有星球。小 p 掌管一家物流公司,該公司有很多個運輸計畫,每個運輸計畫形如 有一艘物 流飛船需要從 ui 號星球沿最快的宇航路徑飛行到 vi 號星球...

解題報告 NOIP2015 子串

這是一道dp題,然後來想想怎麼表示狀態,對答案有影響的就是a串的第i個字元,b串的第j個字元,和k個子串,簡單來說就是和選取的字元和子串的數量有關.那麼設 f i j kk 表示在a串的前i個字元中選kk個子串匹配b串的前j個字元的方案數.求方案數可以採用加法原理,考慮a串的第i個字元,那麼這個字元...

NOIP2015運輸計畫題解報告

這題在洛谷上可以找到提交 p2680運輸計畫 公元 2044 年,人類進入了宇宙紀元。l 國有 n 個星球,還有 n 1 條雙向航道,每條航道建立在兩個星球之間,這 n 1 條航道連通了 l 國的所有星球。小 p 掌管一家物流公司,該公司有很多個運輸計畫,每個運輸計畫形如 有一艘物 流飛船需要從 u...