Luogu P2513. [HAOI2009]逆序对数列
#include <lastweapon/io>
using namespace lastweapon;
const int N = int(1e3) + 9;
int f[N];
int n, m;
int main(){
#ifndef ONLINE_JUDGE
//freopen("in.txt", "r", stdin);
#endif
RD(n, m); f[0] = 1;
FOR(i, 1, n) {
DWN_1(j, m, 1) {
int t = max(0, j-i);
DWN(k, j, t) f[j] += f[k];
f[j] %= 10000;
}
}
cout << f[m] << endl;
}
#include <lastweapon/io>
using namespace lastweapon;
const int N = int(1e3) + 9;
int f[N], s[N];
int n, m;
int main(){
#ifndef ONLINE_JUDGE
//freopen("in.txt", "r", stdin);
#endif
RD(n, m); f[0] = 1;
FOR(i, 1, n) {
REP(j, m) s[j+1] = s[j] + f[j];
DWN_1(j, m, 1) {
f[j] += s[j] - s[max(0, j-i)];
f[j] %= 10000;
}
}
cout << f[m] << endl;
}
Luogu P2511. [HAOI2008]木棍分割
这个暴力反而不太好写。。。对于每个状态,大概需要分别有 best[i][j], ways[i][j] 表示长度为 j 恰好切 i 段,时的最优解和方案数。
但转移的方程里面有 max() 导致非常难以优化。
进一步我们发现 best 是可以直接二分出来的。。。有了最大切痕长度,在考虑 dp 方案数就简化非常多了。。(此时我们在最后的最大切痕一定等于 best。。即使中间允许不满足)
#include <lastweapon/io>
using namespace lastweapon;
const int N = int(5e4) + 9;
int a[N], s[N], lt[N]; int ways[N], sums[N];
int n, m, p, q;
bool ok(int x) {
int cur = 0, cnt = 0;
REP_1(i, n) {
if (cur + a[i] > x) cur = 0, ++cnt;
cur += a[i];
}
return cnt <= m;
}
int get_cut() {
int l = *max_element(a+1, a+n+1), r = s[n];
while (l < r) {
int m = (l + r) / 2;
if (ok(m)) r = m;
else l = m + 1;
}
return l;
}
int main() {
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
#endif
MOD = 10007;
RD(n, m); REP_1(i, n) s[i] = s[i-1] + RD(a[i]);
int cut = get_cut();
int l = 0; REP_1(i, n) {
while (s[i] - s[l] > cut) ++l;
lt[i] = l;
}
REP_1(i, n) if (s[i] <= cut) ways[i] = 1; else break;
int tot = ways[n];
REP_1(i, m) {
REP(j, n) sums[j+1] = sums[j] + ways[j];
REP_1(j, n) {
ways[j] = (sums[j] - sums[lt[j]]) % MOD;
if (ways[j] < 0) ways[j] += MOD;
}
tot += ways[n];
}
tot %= MOD;
printf("%d %d\n", cut, int(tot));
}
P3515 [POI2011]Lightning Conductor
#include <lastweapon/io>
using namespace lastweapon;
const int N = int(5e5) + 9;
int a[N];
int n;
int main() {
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
#endif
RD(n); REP(i, n) RD(a[i]);
REP(i, n) {
int z = 0;
REP(j, n) {
int t = sqrt(abs(i-j)); if (t*t < abs(i-j)) ++t;
checkMax(z, (a[j] - a[i]) + t);
}
printf("%d\n", z);
}
}




Alca
Amber
Belleve Invis
Chensiting123
Edward_mj
Fotile96
Hlworld
Kuangbin
Liyaos
Lwins
LYPenny
Mato 完整版
Mikeni2006
Mzry
Nagatsuki
Neko13
Oneplus
Rukata
Seter
Sevenkplus
Sevenzero
Shirleycrow
Vfleaking
wangzhpp
Watashi
WJMZBMR
Wywcgs
XadillaX
Yangzhe
三途川玉子
About.me
Vijos
