P9891 [ICPC2018 Qingdao R] Repair the Artwork 题解
所求即为选择的区间恰好包含所有
设所有
设
将所有
只需求满足条件的区间数量,设所有被视为
考虑 DP,发现答案只与
转移
其中
发现容斥系数的指数实际上是有多少个
该式中
边界
答案
#include <iostream> #define int long long using namespace std; const int mod = 1e9 + 7; static inline int qpow(int a, int b) { int ret = 1; while (b) { if (b & 1) ret = ret * a % mod; a = a * a % mod; b >>= 1; } return ret; } int n, m; int a[105]; int dp[105][10005]; static inline void solve() { cin >> n >> m; for (int i = 1; i <= n; ++i) cin >> a[i]; for (int i = 0; i <= n + 1; ++i) { int mx = n * (n + 1) / 2; for (int j = 0; j <= mx; ++j) dp[i][j] = 0; } a[n + 1] = 1; dp[0][0] = 1; for (int i = 0; i <= n; ++i) { int mx = i * (i + 1) / 2; for (int j = 0; j <= mx; ++j) { for (int k = i + 1; k <= n + 1; ++k) { int w = (k - i) * (k - i - 1) / 2; if (a[k] == 1) { dp[k][j + w] = (dp[k][j + w] + dp[i][j]) % mod; break; } else if (a[k] == 2) { dp[k][j + w] = (dp[k][j + w] - dp[i][j] + mod) % mod; } } } } int mx = n * (n + 1) / 2; int ans = 0; for (int i = 0; i <= mx; ++i) ans = (ans + dp[n + 1][i] * qpow(i, m) % mod) % mod; cout << ans << endl; } signed main() { #ifndef ONLINE_JUDGE freopen("P9891.in", "r", stdin); #endif ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); int T; cin >> T; while (T--) solve(); return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?