数学联邦政治世界观
超小超大

数学(九)

C - Minimum Glutton

排序加贪心

int main()

{

std::ios::sync_with_stdio(false);

std::cin.tie(0);

int n;

std::cin>>n;

ll x, y;

std::cin>>x>>y;

std::vector<int> a(n), b(n);

for (int i = 0; i<n; i++)

{

std::cin>>a[i];

}

for (int i = 0; i<n; i++)

{

std::cin>>b[i];

}

std::sort(a.rbegin(), a.rend());

std::sort(b.rbegin(), b.rend());

int ans = n;

ll sum = 0;

for (int i = 0; i<n; i++)

{

sum += a[i];

if (sum>x)

{

ans = std::min(ans, i + 1);

break;

}

}

sum = 0;

for (int i = 0; i<n; i++)

{

sum += b[i];

if (sum>y)

{

ans = std::min(ans, i + 1);

break;

}

}

std::cout<<ans<<"\n";

return 0;

}

D - K-th Nearest

二分到b 的距离

int main()

{

std::ios::sync_with_stdio(false);

std::cin.tie(0);

int n, q;

std::cin>>n>>q;

std::vector<int> a(n);

for (int i = 0; i < n; i++)

{

std::cin>>a[i];

}

std::sort(a.begin(), a.end());

while (q--)

{

int b, k;

std::cin>>b>>k;

auto check = [&](int dis)

{

int p1 = std::lower_bound(a.begin(), a.end(), b - dis) - a.begin();

int p2 = std::upper_bound(a.begin(), a.end(), b + dis) - a.begin() - 1;

return p2 - p1 + 1<k;

};

int l = -1, r = 2e8;

while (l<r)

{

int mid = (l + r + 1) / 2;

if (check(mid))

l = mid;

else

r = mid - 1;

}

std::cout<<l + 1<<"\n";

}

return 0;

}

E - Maximum Glutton

到E 直接开始破防,确实是 dp 功力还不行

枚举前面i 个里面选 j 个,甜度不超过 k 的最小代价,然后可以把第一维滚掉

int main()

{

std::ios::sync_with_stdio(false);

std::cin.tie(0);

int n;

std::cin>>n;

int x, y;

std::cin>>x>>y;

std::vector<int> a(n + 1), b(n + 1);

for (int i = 1; i <= n; i++)

{

std::cin>>a[i]>>b[i];

}

std::vector dp(n + 1, std::vector<int>(x + 1, y + 1));

dp[0][0] = 0;

for (int i = 1; i <= n; i++)

{

auto ndp = dp;

for (int j = 1; j <= i; j++)

{

for (int k = a[i]; k <= x; k++)

{

ndp[j][k] = std::min(ndp[j][k], dp[j - 1][k - a[i]] + b[i]);

}

}

dp.swap(ndp);

}

int ans = 0;

for (int j = 0; j<n; j++)

{

for (int k = 0; k <= x; k++)

{

if (dp[j][k] <= y)

ans = std::max(ans, j + 1);

}

}

std::cout<<ans<<'\n';

return 0;

}

F - Range Connect MST

赛时没仔细想盲猜线段树优化建图然后就一直冲E 去了,打完一看直接升温

可以将图分成两个部分一边是1 ∼ N,另一边是 N+1 ∼ N+Q,操作完第二个部分所有节点一定会连到第一个部分,代价是 ∑Gᵢ,然后只要考虑第一个部分

每次操作会有[Lᵢ,Rᵢ] 中所有点和点 N+i 连接,总共 Rᵢ – Lᵢ+1 条边,相当于 [Lᵢ,Rᵢ] 中的点连成链,然后 N+i 连到这个区间(怎么连不重要),我们只需要暴力把 x 连接到 x+1(x<Rᵢ) 如果 [Lᵢ,Rᵢ] 内某个区间

已经相连,直接跳过这个区间,这个操作用并查集很容易实现,根据上面连接方式,每个点的祖先一定大于或者等于它,最后只要判断 1 的祖先是不是 N 判断是否连通

至于最小生成树问题,存下每次询问然后排序

struct DSU

{

int n;

std::vector<int> fa, size;

DSU(int n) : n(n), fa(n + 1), size(n + 1, 1) { std::iota(fa.begin(), fa.end(), 0); }

int find(int x)

{

if (x != fa[x])

{

fa[x] = find(fa[x]);

}

return fa[x];

}

void merge(int x, int y) // x -> y

{

x = find(x), y = find(y);

if (x == y)

return;

// if (size[x]>size[y])

// std::swap(x, y);

fa[x] = y, size[y] += size[x];

}

bool same(int x, int y)

{

return find(x) == find(y);

}

};

int main()

{

std::ios::sync_with_stdio(false);

std::cin.tie(0);

int n, q;

std::cin>>n>>q;

std::vector<std::array

for (auto &[c, l, r] : quries)

{

std::cin>>l>>r>>c;

}

std::sort(quries.begin(), quries.end());

ll ans = 0;

DSU dsu(n);

for (auto [c, l, r] : quries)

{

ans += c;

int x = dsu.find(l);

while (x<r)

{

dsu.merge(x, x + 1);

x = dsu.find(x);

ans += c;

}

}

if (dsu.find(1) != n)

{

ans = -1;

}

std::cout<<ans<<'\n';

return 0;

}

G - Last Major City

前有典题...

斯坦纳树,模板代码几乎原封不动放上去就能过,原理得仔细学习,代码倒是很简单

dp[S][i]表示以 i 为根,节点集合为 S 的最小路径长,有

dp[S][i]=min(dp[S][i],dp[T][i]+dp[S ⨁ T][i]),T ⊆ S

然后再对 S 做一个最短路就可以了

int main()

{

std::ios::sync_with_stdio(false);

std::cin.tie(0);

int n, m, k;

std::cin>>n>>m>>k;

std::vector<std::vector<std::pair<int, int>>> g(n);

for (int i = 0; i<m; i++)

{

int a, b, c;

std::cin>>a>>b>>c;

a--, b--;

g[a].push_back({b, c});

g[b].push_back({a, c});

}

const ll inf = 1e18;

std::vector dp(1<<(k - 1), std::vector<ll>(n + 1, inf));

for (int i = 0; i<k - 1; i++)

{

dp[1<<i][i] = 0;

}

for (int s = 1; s<(1<<k - 1); s++)

{

for (int t = (s - 1) & s; t>0; t = (t - 1) & s)

{

for (int i = 0; i<n; i++)

{

dp[s][i] = std::min(dp[s][i], dp[t][i] + dp[s ^ t][i]);

}

}

// dij

std::priority_queue<std::pair<ll, int>> q;

std::vector<bool> vis(n);

for (int i = 0; i<n; i++)

{

if (dp[s][i] != inf)

q.push({-dp[s][i], i});

}

while (!q.empty())

{

auto [_, x] = q.top();

q.pop();

if (vis[x])

continue;

vis[x] = 1;

for (auto [y, w] : g[x])

{

if (dp[s][x] + w<dp[s][y])

{

dp[s][y] = dp[s][x] + w;

q.push({-dp[s][y], y});

}

}

}

}

for (int i = k - 1; i<n; i++)

{

std::cout<<dp[(1 << k - 1) - 1][i]<<"\n";

}

return 0;

}

本文使用 Zhihu On VSCode 创作并发布

数学联邦政治世界观提示您:看后求收藏(笔尖小说网http://www.bjxsw.cc),接着再看更方便。

相关小说

我靠养鱼,日常变美 连载中
我靠养鱼,日常变美
寒时温
快穿流,不喜勿入(日更2000~4000)一句话简介:我靠养鱼,日常变美!颜末小姐的鱼塘壮大史。第一处鱼塘:网恋选我,我超甜第二处鱼塘:恋综......
56.4万字2周前
惊世狂妃:皇叔一宠到底 连载中
惊世狂妃:皇叔一宠到底
庄庄2
洞房花烛夜被休,丈夫诬陷她和小叔子滚床单,渣爹毒死她,渣妹还要将她分尸?不是吧不是吧?都这个年代了,还有人受这窝囊气呢?21世纪戏精影后降临......
218.4万字4天前
快穿之芙蓉帐暖 连载中
快穿之芙蓉帐暖
玉樱樱
(快穿+系统+虐渣+爽文+演戏+大美人+渣女+男主碎片)渣女梨依儿快穿到各个小世界围绕在各个大佬周围。完成任务后就不甩他们了,主搞自己的事业......
3.2万字2周前
春日樱花梦 连载中
春日樱花梦
春粉映蓝
《春日樱花梦》是一部描绘少年小枫在春日小镇上的一段奇妙旅行的小说。故事讲述了小枫在一个樱花盛开的午后,被淡紫色的樱花瓣和古老桥梁所吸引,踏上......
0.2万字2周前
(无限流)我就是想交个朋友 连载中
(无限流)我就是想交个朋友
麦穗花
【欢迎来到无限世界[域],在这里,特殊能力唾手可得,死亡更不是梦想,随时随地,身临其境,尖叫和欢笑,惊骇与心动,让我们——娱乐至死!】(ㅍ_......
1.3万字4天前
异世中原 连载中
异世中原
上官青鹤
异世界日记
0.2万字4天前