1. 程式人生 > >CodeForces 946D Timetable

CodeForces 946D Timetable

最小 can div body memset main sig std sizeof

Timetable

題意:ivan 是一個學生, 他們當地一周有n天, 每天有m節課,每節課一小時, 然後‘1’代表的是ivan這個時間段需要上課, 現在ivan可以跳過選擇K節課不去上, 他在學校的時間為當天他選擇的第一節課到當天的最後一節課,也就是可以跳2端的課, 如果當天的沒有課, 當天就不需要去學校。現在求這周ivan去學校的時間最小是多少。

題解:算出不逃課的情況下的總時間, 然後用分組背包(因為每天只能有一種情況, 所以只能在每組裏面選一種),跑出逃課k節下最多的逃課時間是多少, 總時間-逃課時間就是答案了。

代碼:

 1 #include<bits/stdc++.h>
 2
using namespace std; 3 #define LL long long 4 #define ULL unsigned LL 5 #define fi first 6 #define se second 7 #define lson l,m,rt<<1 8 #define rson m+1,r,rt<<1|1 9 #define max3(a,b,c) max(a,max(b,c)) 10 const int INF = 0x3f3f3f3f; 11 const LL mod = 1e9+7; 12 typedef pair<int,int
> pll; 13 const int N = 5e3+10; 14 char str[N]; 15 int dp[N]; 16 int pos[N]; 17 int len[N]; 18 int n, m, k; 19 int main(){ 20 scanf("%d%d%d", &n, &m, &k); 21 int tot = 0; 22 for(int i = 1; i <= n; i++) { 23 scanf("%s", str+1); 24 int cnt = 0; 25 for(int
j = 1; j <= m; j++) 26 if(str[j] == 1) 27 pos[++cnt] = j; 28 if(cnt == 0) continue; 29 memset(len, 0, sizeof(len)); 30 int llen = pos[cnt]-pos[1]+1; 31 tot += llen; 32 for(int to = 1; to <= k && to <= cnt; to++){ 33 for(int r = cnt - to, l = 1; r >= l && r <= cnt; r++, l++) 34 len[to] = max(len[to], llen - (pos[r] - pos[l] + 1)); 35 if(to == cnt) 36 len[to] = llen; 37 } 38 for(int j = k; j >= 1; j--) 39 for(int to = 1; to <= j && to <= cnt; to++) 40 dp[j] = max(dp[j], dp[j-to]+len[to]); 41 } 42 printf("%d", tot - dp[k]); 43 return 0; 44 }

CodeForces 946D Timetable