1. 程式人生 > >CQUPT萌新賽題解(附F代碼)

CQUPT萌新賽題解(附F代碼)

mil 不能 遞推 strcmp 記憶化搜索 代碼 好用 字典 std

題解或許會遲到,但永遠不會缺席(逃

還是感謝qs手下留情和mzjj給弱智一點面子,才讓本蒟蒻拿到了鍵盤(

題目貼了網址也沒意義,鶸校只讓內網進(蘭兒鶸校oj也見不得人

那麽開始正題:

T1,T2:

ORZ直接略過吧.......

T3:

給了個公式,直接用double算會爆精度WA掉(據說記憶化搜索沒事?)

然後可以直接把1-70的答案打印出來找規律,發現這TM不是斐波拉契數列嗎...

所以直接整數遞推之後再printf(".0000")就行了ORZ......

話說這公式就是斐波拉契數列的公式(當然本蒟蒻是不知道的啦)

T4:
c語言課才學了strcmp用法,也算是復習了一下吧(真TM好用,不然就得搞半天一點都不熟練的map了)

直接暴力枚舉每個字符串跟字典裏面的其中一個對的上不,對不上直接輸出,對的上就輸出翻譯後的。

嵌套問題一開始寫了個Floyd,不出所料的T了,略加思索就發現用一個fa數組就可以解決了,對於 i 的翻譯結果為 j 的原單詞的直接fa[ i ] = j,輸出答案的時候直接while(fa[i])到頂就行了,還可以類似並查集思想壓縮一下路徑(不壓縮也能A

T5

裸的線段樹加了區間查詢的時候允許修改左右最多2位....

標程並看不太懂ORZ,還是寫自己的做法吧.....

如果每次查詢都拆開成25次詢問,時間復雜度為O(25*m*logn),鐵定T,所以不能這樣。

我們發現其實這25次裏面中間的查詢都重復了。

所以我們直接用線段樹查[L+2 , R-2]這個區間(如果L+2 >= R-2答案肯定為零,不用查了)

記錄其最大值M和次大值m,然後我們枚舉區間向外延伸的25種情況,每種情況更新的M-m取最小值就是答案了。

時間復雜度為O(m*(logn+25)) ,還行。

T6:

本蒟蒻復習了半天普通dp結果考個狀壓(蘭兒已經很裸了本鶸還是不會

最後45min雙手離開鍵盤進入觀海模式OMZ

狀態和解法在代碼裏面都有:

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cstring>
 4 using
namespace std; 5 const int maxn=1005; 6 const int maxs=3005; 7 struct data 8 { 9 int h,s,a,b,t; 10 }w[15]; 11 int dp[maxn][maxs][15]; 12 int n,p; 13 int main() 14 { 15 16 scanf("%d%d",&p,&n); 17 18 for(int i=1;i<=n;i++) 19 { 20 scanf("%d%d%d%d%d",&w[i].h,&w[i].s,&w[i].t,&w[i].a,&w[i].b); 21 w[i].s=w[i].h-w[i].s; 22 w[i].t=w[i].s-w[i].t; 23 w[i].a=w[i].a+w[i].b; 24 } 25 26 //dp[i][S][j] 精力剩余i,唱歌情況為S,前一首是j的最大滿意度 27 28 //邊界:每首歌當第一首歌的情況,其他狀態全部-inf 29 30 int ans=0,all=(1<<n+1)-1; 31 memset(dp,-100,sizeof(dp)); 32 33 for(int i=1;i<=n;i++) 34 for(int j=w[i].a;j<=p;j++) 35 { 36 dp[j][1<<i][i]=w[i].h; 37 ans=max(ans,w[i].h); 38 } 39 40 for(int i=1;i<=p;i++) 41 for(int S=0;S<=all;S++) 42 for(int j=1;j<=n;j++) if((1<<j)&S) 43 for(int k=1;k<=n;k++) if(i>=w[k].b&&(1<<k)&S) 44 { 45 46 //當前狀態由兩種方式轉移而來:S中原來有k, S中原來沒有k 47 48 if(j==k) dp[i][S][k]=max(dp[i][S][k],dp[i-w[k].b][S][j]+w[k].t); 49 else 50 dp[i][S][k]=max(dp[i][S][k],dp[i-w[k].b][S][j]+w[k].s); 51 52 if(i>=w[k].a) 53 dp[i][S][k]=max(dp[i][S][k],dp[i-w[k].a][S-(1<<k)][j]+w[k].h); 54 55 if(dp[i][S][k]>ans) 56 ans=dp[i][S][k]; 57 } 58 59 printf("%d",ans); 60 return 0; 61 }

還是太菜了,同誌仍需努力啊ORZ.......

CQUPT萌新賽題解(附F代碼)