cf946d 怎样逃最多的课dp

来源:codeforces                                              D. Timetable

Ivan is a student at Berland State University (BSU). There are n days in Berland week, and each of these days Ivan might have some classes at the university.

There are m working hours during each Berland day, and each lesson at the university lasts exactly one hour. If at some day Ivan‘s first lesson is during i-th hour, and last lesson is during j-th hour, then he spends j?-?i?+?1 hours in the university during this day. If there are no lessons during some day, then Ivan stays at home and therefore spends 0 hours in the university.

Ivan doesn‘t like to spend a lot of time in the university, so he has decided to skip some lessons. He cannot skip more than k lessons during the week. After deciding which lessons he should skip and which he should attend, every day Ivan will enter the university right before the start of the first lesson he does not skip, and leave it after the end of the last lesson he decides to attend. If Ivan skips all lessons during some day, he doesn‘t go to the university that day at all.

Given nmk and Ivan‘s timetable, can you determine the minimum number of hours he has to spend in the university during one week, if he cannot skip more than k lessons?

Input

The first line contains three integers nm and k (1?≤?n,?m?≤?500, 0?≤?k?≤?500) — the number of days in the Berland week, the number of working hours during each day, and the number of lessons Ivan can skip, respectively.

Then n lines follow, i-th line containing a binary string of m characters. If j-th character in i-th line is 1, then Ivan has a lesson on i-th day during j-th hour (if it is 0, there is no such lesson).

Output

Print the minimum number of hours Ivan has to spend in the university during the week if he skips not more than k lessons.

Examples

input

Copy

2 5 10100110110

output

5

input

Copy

2 5 00100110110

output

8

思路:想暴力,不过只是想想而已总结:dp好难,和以前遇到的dp一样,都是dp[i][j]代表前i行,状态为j时的最优值,状态的表示比较难,nm数组用来表示当剩下i个1时要花的时间,枚举所有逃课节数,再枚举当前行的逃课数量
#include <bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
char tl[501][501];
int dp[501][501],p[501],mn[501],n,m,kk,c,l;
int main()
{
        cin>>n>>m>>kk;
        for(int i=1;i<=n;i++)
        scanf("%s",tl[i]);
        for(int i=1;i<=n;i++)
        {
            c=0;
            for(int j=0;j<m;j++)
                if(tl[i][j]==‘1‘)
                    p[++c]=j;
            for(int j=1;j<=c;j++)
            {
                mn[j]=501;
                for(int k=1;k+j-1<=c;k++)
                    mn[j]=min(mn[j],p[k+j-1]-p[k]+1);
            }
          for(int j=0;j<=kk;j++)
          for(l=min(c,j),dp[i][j]=INF;l>=0;l--)
            dp[i][j]=min(dp[i][j],dp[i-1][j-l]+mn[c-l]);
        }
    cout<<dp[n][kk]<<endl;
    return 0;
}

原文地址:https://www.cnblogs.com/carcar/p/8540688.html

时间: 2024-10-03 14:38:01

cf946d 怎样逃最多的课dp的相关文章

Timetable CodeForces - 946D (区间dp)

大意: n天, 每天m小时, 给定课程表, 每天的上课时间为第一个1到最后一个1, 一共可以逃k次课, 求最少上课时间. 每天显然是独立的, 对每天区间dp出逃$x$次课的最大减少时间, 再对$n$天dp即可. #include <iostream> #include <sstream> #include <algorithm> #include <cstdio> #include <math.h> #include <set> #i

[博弈dp] hdu 4778 Gems Fight

给出g种颜色的宝石,然后有B个背包,S代表到时候每种颜色的宝石凑齐S个能变成一个魔法石 然后B行数输入,每个包里有哪些宝石 然后A,B轮流拿包,每个包只能拿一次,拿出包把宝石放地上. 如果能变成魔法石则拿走魔法石,下一次还这个人拿包,没变成则换人. 魔法石的个数就是获得分数,问两人最优的时候分差是多少. 思路: 只有21个包,状压dp. 然后发现不管顺序如何 最后构成的魔法石的个数是一定的. 然后在不同的二进制状态下,所剩在地面上的宝石是一定的. 那么就可以dp[i] 代表i这个状态下 先手取所

dp入门 专题记录 2017-7-26

POJ3176-Cow Bowling 题目大意:现有n行数,以金字塔的形式排列,即第一行一个数字,第二行2个数字,依次类推,现在需要找一条从第一层到第n层的路线,使得该路线上的所有点的权值和最大 思路:根据分析可以得出状态转移方程:dp[i][j]=max(dp[i-1][j],dp[i-1][j-1]),dp[i][j]表示以第i行第j个位置作为终点的的线路中的最大权值. #include <iostream> using namespace std; const int N = 360;

POJ 2029 DP || 暴力

在大矩形中找一个小矩形 使小矩形包含的*最多 暴力或者DP  水题 暴力: #include "stdio.h" #include "string.h" int main() { int n,m,w,i,s,t,j,k,l,ans,sum,x,y; int map[101][101]; while (scanf("%d",&w)!=EOF) { if(w==0) break; scanf("%d%d",&n,&

UVA - 11825 状压DP

该题目是EMAXX推荐的练习题,刘汝佳的书也有解说 如果S0属于全集,那S0就可以作为一个分组,那么S分组数可以是best{当前S中S0的补集+1} 对于集合类的题目我觉得有点抽象,希望多做多理解把 #include<iostream> #include<algorithm> #include<cstdio> #include<cstring> #include<cstdlib> #include<cmath> #include<

区间dp①

打算一次写完,看情况吧. 少女祈祷中... 区间dp,大概是对区间的动态规划,每个大区间的决策都是由小区间的决策转移过来. 然后看道例题:石子合并  noi1995 设有 N 堆沙子排成一排,其编号为 1,2,3,-,N(N<=300).每堆沙子有一定的数量,可以用一个整数来描述,现在要将这 N 堆沙子合并成为一堆,每次只能合并相邻的两堆,合并的代价为这两堆沙子的数量之和,合并后与这两堆沙子相邻的沙子将和新堆相邻,合并时由于选择的顺序不同,合并的总代价也不相同,如有 4 堆沙子分别为 1 35

树形dp小结

做了好久的树形DP(大雾) ,(noip)csp-s考了好多树形DP 树形DP基本分为这几种 1.最大独立集(没有上司的舞会) 经典树形DP \(dp[i][0/1]\) 表示i这个点选与不选. \(dp[u][0] += dp[v][1];\) \(dp[u][1] += max(dp[v][0],dp[v][1]);\) 2.最小点覆盖(战略游戏) 状态与上面一样 \(dp[u][0] += dp[v][1];\) \(dp[u][1] += min(dp[v][0],dp[v][1]);\

HDU1074:Doing Homework(状压DP)

Doing Homework Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 15868    Accepted Submission(s): 7718 Problem Description Ignatius has just come back school from the 30th ACM/ICPC. Now he has a l

Codeforces 946D Timetable(预处理+分组背包)

题目链接:http://codeforces.com/problemset/problem/946/D 题目大意:有n个字符串,代表n天的课表,1表示这个时间要上课,0表示不要上课,一天在学校时间为第一节课到最后一节课的时间.总共,可以逃过k次课,求至少需要在学校多少时间. 解题思路:听了大佬说背包,然后预处理就想了20多分钟,比赛结束,GG...先是预处理出v[i][k]即第i天逃k节课的能节约的最多时间,至于怎么求,直接枚举k,然后枚举两端1的位置即可.然后就可以做分组背包了,这就不说了,很