ARC065 簡要題解

2022-05-07 22:03:11 字數 1128 閱讀 2235

從前往後不好做, 那就直接從後往前

考慮設 \(f[i][j]\) 為在第一張圖中屬於 \(i\) 集合, 在第二張圖中屬於 \(j\) 集合的點的個數

這樣會 mle , 但是又發現有用的 \((i, j)\) 不會很多, 直接 \(map\) 存下來就行了

轉化為切比雪夫距離之後直接從起點 bfs , 把橫縱座標離散化之後存在 set 中, 找到乙個就刪掉他, 這樣就可以保證 bfs 的複雜度是對的了

然後對於每個點算一次貢獻

發現乙個點對會算兩次, 最後把答案除以二就行了

互相包含的區間是沒有用的, 證明的話考慮把小的那個區間挖出去

然後就可以把所有的區間變成左端點和右端點都單調遞增的區間了

那麼乙個區間控制的範圍就是他的左端點到 min(他的右端點, 下乙個區間的左端點 - 1)

設 \(f[i][j]\) 為前 \(i\) 個點控制的範圍中放置了 \(j\) 個 1 並且合法的方案

列舉乙個 \(k\) 然後從 \(f[i - 1][j - k]\) 轉移過來, 乘個組合數就行了

複雜度 \(o(n^3)\) , 但根據網上題解的說法, 複雜度是 \(o(n ^ 2)\) 的

有點沒講清楚細節, 放下**吧

#include #include #include #include const int n = 3e3 + 5;

const int mod = 1e9 + 7;

using namespace std;

int n, m, a[n], l[n], r[n], vis[n], sum[n], c[n][n], f[n][n], mx[n], len[n];

struct node

} p[n];

char s[n];

template < typename t >

inline t read()

while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();

return x * w;

}int main()

printf("%d\n", f[m][sum[n]]);

return 0;

}

ARC068 簡要題解

任意一面朝上直接 5 6 5 6 或者 6 5 6 5 然後就沒了 首先把牌張數大於三張的丟到三張以下 設還有兩張的有 k 個 如果 k 是 2 的倍數,那麼可以直接全扔了 如果不是,需要找到乙個只有一張牌的扔掉才能把這 k 個扔掉 拿個桶記一下 長度 geq len 的區間中必然存在 len 的倍...

ARC063 簡要題解

模擬即可 算下有多少個極大差就行了 考慮乙個點到另乙個點的路徑是什麼情況 必然是一段上公升的加一段下降的,單增單減也行 然後就可以考慮乙個貪心策略了 每次選出最小的,給他周圍沒有附權值的附乙個 這個最小點權值 1 的權值 不難發現這樣是滿足上面那個條件的 不合法情況中間判一下就行 考試考過,想出來了...

ARC058 簡要題解

暴力列舉然後 check 一下 設左上角的點座標為 1,h 右下角的點座標為 w,1 補集轉化之後就只用求必須經過左下角那個矩形的方案數了 考慮無論怎麼走必須要從矩形右邊的那一條 b,a b,1 線段經過 列舉一下最後經過的哪個點即可 妙補集轉化之後求不存在滿足題意條件的方案數 看到資料範圍容易想到...