codeforces 946D Timetable(DP)

题意:一个星期有n天,每天m小时,一小时一节课,每天一个01字符串0代表没课,1代表有课,一个星期可以翘k节课,一天在学校的时间为你去上的第一节课到最后一节课,问你一个星期最少的在学校待的时间。

思路:对于每天,暴力出数组t,t[i]=x代表该天上i小时课最少x小时在学校。就可以dp出dp数组。dp[i]=x代表这个星期上i节课最少多少小时在学校。

转移方程 dp[i] = min(dp[i],dp[i-j]+t[j]);

注意 i从sum到sum-k;(sum为当前天时,一共能上的课) j从0到min(len,i) (len为今天能上的课);不然会超时!!

#include <bits/stdc++.h>
using namespace std;
const int maxn =  2e3+50;
int pos[505],t[505];
int dp[250050];
int main()
{
//    freopen("in.txt", "r", stdin);
    ios::sync_with_stdio(false);
    int n,m,kk;
    cin>>n>>m>>kk;
    string str;
    int sum = 0;
    memset(dp,0x3f,sizeof(dp));
    dp[0] = 0;
    for(int i = 1; i<=n; i++)
    {
        cin>>str;
        int len = 0;
        for(int j = 0; j<m; j++)
            if(str[j]=='1')
                pos[len++] = j;

        sum+=len;
        memset(t,0x3f3f3f3f,sizeof(t));//上t节课最少的在校时间
        t[0] = 0;
        if(len) t[1] = 1;

        for(int j = 0; j<len-1; j++)
            for(int k = j+1; k<len; k++)
                t[k-j+1] = min(t[k-j+1],pos[k]-pos[j]+1);

        for(int k = sum; k>=sum-kk; k--)
            for(int j = 0; j<=min(len,k); j++)
                dp[k] = min(dp[k],dp[k-j]+t[j]);
    }
    cout<<dp[sum-kk]<<endl;
    return 0;
}

 

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值