題目鏈結
設 \(f_\) 表示以 \(i\) 結尾的一組選擇了 \(j\) 個數,剩下的也能湊出一組時,剩下一組結尾數的最小值。
當 \(a_>a_i\) 時,\(i\) 與 \(i+1\) 可以分到一組,因此 \(f_=max(f_,f_)\)
當 \(a_>f_\) 時,\(i+1\) 能分到剩下的一組,該組原有 \(j-i\) 個數,因此 \(f_=max(f_,a_i)\)
#include #include #include #include using namespace std;
const int n = 2333;
int n, a[n], f[n][n];
int main()
if(f[n][n / 2] != 0x3f3f3f3f) printf("yes!\n");
else printf("no!\n");
}return 0;
}
題目鏈結
設 \(f_\) 表示前 \(i\) 個積木搭成的左塔和右塔差為 \(j\) 時,左邊的塔的最大高度
\(1.\) 不放如當前積木
\(f_=max(f_,f_)\)
\(2.\) 當前積木放在左邊
\(f_=max(f_,f_+a_i)\)
\(3.\) 當前積木放在右邊
\(f_=max(f_,f_)\)
注意:\(1.\) 差值可能為負數,根據資料範圍,\(j\) 直接加上 \(500000\)
\(2.\) 注意記憶體,使用滾動陣列優化
#include #include #include using namespace std;
const int p = 500000;
int n, ans = 0, a[51], f[2][1000001];
int main()
if(ans != 0) printf("%d", ans);
else printf("-1");
return 0;
}
題目鏈結
歷年真題,wa 到生活不能自理
首先考慮鏈的情況,若當前走到 \(x\)
\((s_x==')')\),計算以當前位置為結尾的合法括號串個數記為 \(f_x\)。
首先不考慮多個合法括號串並列的情況,這樣的括號串有且僅有乙個
。用棧維護與其配對的前括號 \(y\),\(x\) 與 \(y\) 之間組成乙個單獨的以 \(x\) 為結尾的合法括號串 \(s\),因此 \(f_x++\);若考慮並列情況,每乙個以 \(y-1\) 為結尾的合法括號串都可以與 \(s\) 並列形成乙個新的合法括號串,\(f_x+=f_\)。綜上 \(f_x=f_+1\)。
用 \(sum_x\) 表示走到 \(x\) 時所有的合法括號串,則 \(sum_x=sum_+f_x\)。樹上的情況也大致相同,一定要注意回溯的寫法(非這樣寫不可,否則會 wa 到起飛)
#include #include #include #include using namespace std;
const int n = 2333333;
struct edge e[n];
long long n, ans = 0, st[n], sum[n], head[n], f[n], fa[n], top = 0, cnt = 0;
char s[n];
void add(long long x, long long y)
; head[x] = cnt;}
void dfs(long long x)
sum[x] = sum[fa[x]] + f[x];
ans ^= sum[x] * x;
for(long long i = head[x]; i; i = e[i].nxt) dfs(e[i].to);
if(s[x] == '(') top--;
else if(y) st[++top] = y;}
int main()
dfs(1);
printf("%lld", ans);
return 0;
}
題目鏈結
不想寫了抄題解罷...(其實是寫不好)
考慮二分答案 \(mid\),原問題變為判定是否存在一種方案,在給定天數內使得兩個軟體都能至少被完成 \(m\) 個模組。
我們設 \(f_\) 表示已經處理到第 \(i\) 個技術人員,第乙個軟體完成 \(j\) 個模組時第二個軟體最多能完成多少個模組,則狀態轉移方程為:
\(f_=max(f_+\frac)\)
表示第 \(i\) 個技術人員第乙個軟體完成 \(k\) 個模組,則第二個軟體最多完成 \(\frac\) 個模組。
最後若 \(f_>=m\) 則答案合法,時間複雜度為 \(o(nm^2log_)\)
注意邊界!
#include #include #include #include using namespace std;
const int n = 1100;
int n, m, ans, l = 0, r = 0, d1[n], d2[n], f[n][n];
bool check(int x)
int main()
while(l + 1 < r)
if(check(l)) ans = l;
else ans = r;
printf("%d", ans);
return 0;
}
數字DP做題記錄
xdu1161 一本通1588 思路 用二維陣列dp i j 表示數字取到i位的情況下,各位數字之和對題中所給n取模為j的數字個數。例如對於樣例來說,dp 1 0 表示數字最多可取到1位,各個位之和對9取模為0個數字個數,這樣的數字有兩個,即0和9。類似地,dp 1 1 1,因為1 9 1 dp 1...
ACM數學題做題記錄
僅以此部落格記錄每次遇到的數論,以便日後的複習 口胡 根本不可能再看 1.2020icpc 小公尺 網路選拔賽第一場 intelligent warehouse 數學 2.2020牛客noip賽前集訓營 提高組 第一場 牛牛的方程式 求解不定方程 3.math problem 2017廣西邀請賽 矩...
KMP做題記錄
題目太長不貼了 這道題很巧妙,給定乙個字串s,求最少在首尾新增幾個字元後,s變為乙個迴圈了n次的字串 n 1 假設我們有乙個迴圈串s abcabcabc 我們根據kmp求一次next陣列,就可以通過next strlen s 得到乙個迴圈節的位置從而求出迴圈節的長度,顯然,迴圈節能被s整除。如果s ...