校內模擬 神光

2022-05-05 21:12:11 字數 1850 閱讀 2999

看到\(「l 的最小值」\),很容易想到二分答案,那麼這道題的關鍵就是如何快速地檢驗

首先,如果已經規定了操作順序,我們可以\(o(n)\)貪心求解

但是要列舉順序的話複雜度是階乘級別的,顯然布星

於是考慮\(dp\),我一開始的\(dp\)狀態:\(dp[i][j]\)表示乾掉前\(i\)個\(fa\)壇,用\(j\)次紅光時的最少用多少次綠光

發現轉移有些麻煩,又因為時間不大夠了,我就隨機操作順序+貪心\(100\)次了(騙到\(60\)分)

題解的做法:

\(dp[i][j]表示用i次\color和j次\color最多摧毀從1開始多少個連續的法壇\)

轉移就是

\[dp[i][j]=p[dp[i-1][j]+1]+q[dp[i][j-1]+1]

\]其中\(p[k]\)表示從第\(k\)個法壇開始向右\(l\)長度內有多少法壇,\(q[k]\)表示從第\(k\)個法壇開始向右\(2l\)長度內有多少法壇,都可以在\(dp\)前預處理出來

\(60\)分隨機演算法:

#include#include#include#include#include#includeusing namespace std;

const int n=2010;

int n,r,g,a[n];

inline bool check(int l)

else if(tot2!=g)

else break;

} if(dr>a[n]) return 1;

} return 0;

}int main()

for(int i=1;i<=n;++i)

scanf("%d",&a[i]);

sort(a+1,a+1+n);

int l=1,r=1000000000;

while(l>1;

if(check(mid)) r=mid;

else l=mid+1;

} printf("%d\n",l);

fclose(stdin); fclose(stdout);

return 0;

}

\(100\)分**

#include#include#include#includeusing namespace std;

#define n 2010

#define reset(a) memset(a,0,sizeof(a))

int n,r,g,a[n],dp[n][n];

int p[n],q[n];

bool check(int l)

p[n+1]=q[n+1]=n;

for(int i=0;i<=r;i++)

for(int j=0;j<=g;j++)

return dp[r][g]==n;

}int main()

for(int i=1;i<=n;i++)

scanf("%d",&a[i]);

sort(a+1,a+1+n);

int l=1,r=1e9;

while(l>1;

if(check(mid)) r=mid;

else l=mid+1;

} printf("%d\n",l);

fclose(stdin); fclose(stdout);

return 0;

}

模擬 神奇的樹

time limit 1000ms memory limit 65536k sdut有一顆神奇的蘋果樹。假如某天早上這樹上有x個蘋果,那麼這樹這一天會再結出x個蘋果來,也就是說到了晚上會有2 x個蘋果,到了深夜,會有專人人來摘蘋果,而摘蘋果的人總會使蘋果數剩下當前數量對m的餘數,也就是說假如當前數量...

校內模擬 鎖

沒有標籤是因為我真的不知道這算什麼型別 這題我說不來大意你們還是看題面描述吧 小z住的房子一共有n個人,他們每人有乙個重要度。房子的門上可以裝若干把鎖。假設共有k把鎖,命名為1到k。每把鎖有一種對應的鑰匙,也用1到k表示。鑰匙可以複製若干份並發給任意多個居民。每個人都可以持有若干鑰匙,可以不持有鑰匙...

校內模擬 assignment(DP)

題面見校內oj4693 考慮預處理f k i j f k i j f k i j 表示最長的一段不超過k kk的時候,將長度為i ii的序列分為j jj段的方案數。在k kk相同的狀態之間轉移,顯然有f i j f i 1 j f i 1 j 1 f i k 1 j 1 f i j f i 1 j ...