CF946D Timetable

题目链接

  题目的大意是Ivan他一周的课表是已知的,用一串01串来表示一天的上课情况,1表示的这个时间段是有课的0表示的是没有课的。现在Ivan这一周可以翘k节课,求出来Ivan在学校的最短时间应该是多长。
  因为每一天只有翘掉首尾的课是可以减少这一天对答案的贡献的,所以翘课的时候应该选择对首尾的1进行处理,这样才能够减少在学校的时间。在处理每一天的时候,我们应该去维护mn[i][j]表示在第i天翘j节课的最小在校时间是多久。处理完每一天的之后,dp[i][j]dp[i1][jlen]+mn[i][len]来更新。

#include <bits/stdc++.h> using i64 = long long; int n, m, k; i64 dp[510][510]; int p[510], mn[510][510], a[510]; char s[510]; int main() { scanf("%d%d%d", &n, &m, &k); memset(mn, 0x3f, sizeof mn); for (int i = 1; i <= n; i ++ ) { scanf("%s", s + 1); int len = 0; for (int j = 1; j <= m; j ++ ) if (s[j] & 1) a[++ len] = j; mn[i][len] = 0; p[i] = len; for (int j = 1; j <= len; j ++ ) { for (int t = j; t <= len; t ++ ) { mn[i][len - (t - j + 1)] = std::min(mn[i][len - (t - j + 1)], a[t] - a[j] + 1); } } } memset(dp, 0x3f, sizeof dp); for (int i = 0; i <= k; i ++ ) dp[0][i] = 0; for (int i = 1; i <= n; i ++ ) { for (int j = 0; j <= k; j ++ ) { for (int t = 0; t <= std::min(p[i], j); t ++ ) { dp[i][j] = std::min(dp[i][j], dp[i - 1][j - t] + mn[i][t]); } } } printf("%lld\n", dp[n][k]); return 0 ^ 0; }

__EOF__

本文作者HoneyGrey
本文链接https://www.cnblogs.com/Haven-/p/16244442.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   浅渊  阅读(30)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示