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
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
Given n, m, k 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?
InputThe first line contains three integers n, m 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).
OutputPrint 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 Copy2 5 1output
01001
10110
5input Copy
2 5 0output
01001
10110
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; }
cf946d 怎樣逃最多的課dp