最初の2019ハング電動マルチ学校
少し自閉症は、昨日書かれているはず、今日ドラッグ
ブランク1001
upsolved
タイトルの意味であり、\(\ N-)のみを埋める、いくつかの位置を埋めるために\(0,1,2,3 \) 4、そこさの\(m個\)の異なるセクションの数を制限し、制約を数カウント充填しようとするプログラム\(1 <= N、M <= 100 \)を
あなたは理解する問題への公式解決策を見てみます
\(DP [I] [J ] [K] [T] \) 代表記入前に\(Tを\)数字の4種類のソートされ出現位置番号かなり小さくした後\(I、J、K、 T \ )、同様に右端に印加するプログラム、制約条件の数が判定される\(T \)そのディメンションは、時間複雑度ロールオフすることができる\ ^の(O(テネシー州4)\) (なぜなら\(I、J 、K、Tの\)一定となるよう命じ)の空間よりもはるかに少ない複雑\(O(N ^ 3) \)
#include <bits/stdc++.h>
using namespace std;
const int N = 101, mod = 998244353;
int dp[N][N][N][2], T, n, m, l, r, x, ans;
vector<pair<int, int>> cons[N];
void addmod(int &x, int y) {
x += y;
if(x >= mod)
x -= mod;
}
int main() {
scanf("%d", &T);
while(T--) {
ans = 0;
scanf("%d%d", &n, &m);
for(int i = 1; i <= m; ++i) {
scanf("%d%d%d", &l, &r, &x);
cons[r].push_back({l, x});
}
for(int i = 1; i <= n; ++i)
cons[i].push_back({i, 1});
memset(dp, 0, sizeof(dp));
dp[0][0][0][0] = 1;
for(int cur = 1; cur <= n; ++cur) {
int o = cur & 1;
for(int i = 0; i <= cur; ++i)
for(int j = i; j <= cur; ++j)
for(int k = j; k <= cur; ++k)
dp[i][j][k][o] = 0;
for(int i = 0; i <= cur; ++i)
for(int j = i; j <= cur; ++j)
for(int k = j; k <= cur; ++k) {
addmod(dp[j][k][cur - 1][o], dp[i][j][k][o ^ 1]);
addmod(dp[i][k][cur - 1][o], dp[i][j][k][o ^ 1]);
addmod(dp[i][j][cur - 1][o], dp[i][j][k][o ^ 1]);
addmod(dp[i][j][k][o], dp[i][j][k][o ^ 1]);
}
for(int i = 0; i <= cur; ++i) {
for(int j = i; j <= cur; ++j)
for(int k = j; k <= cur; ++k)
for(auto c : cons[cur]) {
l = c.first, x = c.second;
if((i >= l) + (j >= l) + (k >= l) + (cur >= l) != x)
dp[i][j][k][o] = 0;
}
}
}
for(int i = 0; i <= n; ++i)
for(int j = i; j <= n; ++j)
for(int k = j; k <= n; ++k)
addmod(ans, dp[i][j][k][n & 1]);
printf("%d\n", ans);
for(int i = 1; i <= n; ++i)
cons[i].clear();
}
return 0;
}
1002操作
upsloved
力によって、各直列問い合わせ間隔加算器または排他的または最大のサブセットの端に
究極の自閉症、cf1100Fオリジナルタイトル(オンライン練習がある)、この問題、それは私がした冬に来ます。。。その後、5時間がそれを見ていない見ました。。。
記録することである(\ \ N-)接頭線形基、直鎖状の基は、さらに現在位置の数の挿入位置を維持し、貪欲の挿入が最大値をとり、特定の説明はcf1100F見出すことができます
1004バケーション
午前2時40分で解きます
そこ(N + 1 \)\車は、車の前に近いが、時間の終わりに到達するために車を依頼する端から遠く離れに行くことができ、追い越すことはできませんが、各車両は最高速度の長さと、端からの距離があり、
彼のチームメイトの半分は、解答の練習を思い付い
リニアアプローチ:最後の車の端から最も遠いは間違いであり、いくつかの他の車両は、年末まで一緒に(それ自身でよい)\(O(N)\)列挙がうまく最大値をとり、
1005パス
2:06で解決
有向グラフのエッジがこのエッジ長の除去のコストで、そのようなから最小のコストを必要とする、ある\(1 \)に\(N- \)の最短経路が長くなります
ライン上の最小カットを実行するための新たな計画を構築するための道路の最短辺アウト
彼のチームメイトは、新しいマップ点マーククレイジー構築しませんでした\({\ RM MLEを} \) ...
1006タイプライター
upsolved
最小のコストを持つターゲット文字列の建設は、次の2回の操作で始まる空の文字列を持っています
\(1 \) :過ごす(のp \)\あなたの最後にコストプラス文字列
\(2 \) :過ごす(q個\)\あなたの文字列のあなたにコスト最後のプラス任意のサブストリングの文字列を
偽のタイトルをゲームをお読みください。。。
二つの位置を維持する\(I、Jの\)
\(S [1:J- 1] \) に挿入される(\ {\ RM SAMは} \) 、次いで見える\(sは[jが:i]が \) されていない\(S [1:J- 1] \) のサブ
ない挿入する(S [j]は、jの\を \ ++)
それは\(DP [I] =分 (DP [I - 1] + P、DP [J-1] + Q])\)
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 10;
int nxt[N << 1][26], len[N << 1], par[N << 1];
int sz, last;
char s[N];
int n, p, q;
long long dp[N];
int newnode(int l) {
len[sz] = l;
memset(nxt[sz], 0, sizeof(nxt[sz]));
return sz++;
}
void init() {
sz = last = 0;
par[sz] = -1;
newnode(0);
}
void add(int x) {
int p = last, np = newnode(len[last] + 1);
for(; ~p && !nxt[p][x]; p = par[p]) nxt[p][x] = np;
if(p == -1) {
par[np] = 0;
}
else {
int q = nxt[p][x];
if(len[q] == len[p] + 1) {
par[np] = q;
}
else {
int nq = newnode(len[p] + 1);
memcpy(nxt[nq], nxt[q], sizeof(nxt[nq]));
par[nq] = par[q];
par[q] = par[np] = nq;
for(; ~p && nxt[p][x] == q; p = par[p])
nxt[p][x] = nq;
}
}
last = np;
}
int main() {
while(~scanf("%s%d%d", s + 1, &p, &q)) {
init();
n = strlen(s + 1);
int cur = 1, now = 1, pos = 0;
while(cur <= n) {
int x = s[cur] - 'a';
if(nxt[pos][x]) {
pos = nxt[pos][x];
dp[cur] = min(dp[cur - 1] + p, dp[now - 1] + q);
cur++;
}
else if(cur == now) {
add(x);
dp[cur] = dp[cur - 1] + p;
cur++;
now++;
}
else {
add(s[now++] - 'a');
int tlen = cur - now;
while(~pos && ~par[pos] && len[par[pos]] >= tlen)
pos = par[pos];
}
}
printf("%lld\n", dp[n]);
}
return 0;
}
1009文字列
upsolved
レースチームメイトはやって言ったが、私は1002年に...私は本当に料理しています
与えられた文字列の長さ選択\(K \)ターゲット文字列を構成する配列は、辞書最小も与えられ、必要な\(26 \)の発生の種文字の数上限と下限新しい文字列で
直接貪欲は逃げます。。。
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10, knd = 26;
char s[N];
int L[knd], R[knd], cnt[N][knd], c[knd], n, k, nxt[N][knd], pos, tmp, tot;
char ans[N];
bool check(int p, int now) {
if(p < 0) return false;
int x = s[p] - 'a', res = 0, ret = 1;
if(c[x] == R[x]) return false;
c[x]++;
for(int i = 0; i < knd; ++i) {
if(L[i] > c[i]) res += L[i] - c[i];
if(cnt[p][i] - (x == i) < L[i] - c[i]) {
ret = 0;
break;
}
}
if(res > k - now)
ret = 0;
c[x]--;
return ret;
}
int main() {
while(~scanf("%s%d", s, &k)) {
tot = 0;
n = strlen(s);
for(int i = 0; i < knd; ++i) {
scanf("%d%d", &L[i], &R[i]);
tot += R[i];
}
memset(nxt[n], -1, sizeof(nxt[n]));
memset(cnt[n], 0, sizeof(cnt[n]));
memset(c, 0, sizeof(c));
for(int i = n - 1; ~i; --i) {
memcpy(nxt[i], nxt[i + 1], sizeof(nxt[i + 1]));
memcpy(cnt[i], cnt[i + 1], sizeof(cnt[i + 1]));
nxt[i][s[i] - 'a'] = i;
cnt[i][s[i] - 'a']++;
}
pos = -1;
for(int i = 0; i < knd; ++i) {
if(check(nxt[0][i], 1)) {
c[i]++;
pos = nxt[0][i] + 1;
ans[0] = 'a' + i;
break;
}
}
if(pos == -1 || tot < k) {
puts("-1");
continue;
}
for(int i = 1; i < k; ++i) {
for(int j = 0; j < knd; ++j) {
if(c[j] == R[j]) continue;
if(check(nxt[pos][j], i + 1)) {
c[j]++;
pos = nxt[pos][j] + 1;
ans[i] = 'a' + j;
break;
}
}
}
ans[k] = '\0';
printf("%s\n", ans);
}
return 0;
}
1012シーケンス
NTT
1011,1013は、彼のチームメイトの方向を担当しています。。
この料理は本当にまだああ記録されるべき新しい何か物事学習後観客に、何の貢献をプレイしていません。。。