水獭
时间限制(普通/Java) : 1500 MS/ 5000 MS 运行内存限制 : 65536 KByte
总提交 : 93 测试通过 : 24
总提交 : 93 测试通过 : 24
比赛描述
某只水獭酷爱动漫,但是看动画片是很耗时间的,以至于没时间刷题了都。于是,他给她下了个限定,每天只能看T秒的动画片。但是,她今天想看的动画片很多很多,目测在时限内肯定看不完了,只好先计划一下,在时限内看的尽可能多。
水獭想看的动漫有N部,其中每一部都有若干集(第1集、第2集……)这些剧集的观看顺序是不可以调换的,即看完第1集才能看第2集,看完第1、2集后才能看第3集。虽然不能调换顺序,但是她可以选择看到任意一集后放弃这部作品而不用将该部的所有剧集看完。
还要注意的两点:
1、每一集都会完整的看完而不会中途间断。
2、“时限内看得尽可能多”,这是以“集”为单位进行评判的。
那么,请计算出她最多可以看多少集动漫呢?
水獭想看的动漫有N部,其中每一部都有若干集(第1集、第2集……)这些剧集的观看顺序是不可以调换的,即看完第1集才能看第2集,看完第1、2集后才能看第3集。虽然不能调换顺序,但是她可以选择看到任意一集后放弃这部作品而不用将该部的所有剧集看完。
还要注意的两点:
1、每一集都会完整的看完而不会中途间断。
2、“时限内看得尽可能多”,这是以“集”为单位进行评判的。
那么,请计算出她最多可以看多少集动漫呢?
输入
第一行包含一个正整数Q,表示有Q组测试数据(1≤Q≤10);
每组测试数据包含若干行,第一行包含两个正整数N和T,分别表示N部动漫作品(1≤N≤20)和T秒的时限(1≤T≤43200);
接下来N行,第i行先包含一个正整数Ki,表示第i部动漫有Ki集(1≤Ki≤20),紧跟着Ki个正整数Cj(1≤Cj≤5000),依次表示第1、2……集的时长(秒)。
输出
每组测试数据对应一行输出,每行输出仅包含一个整数,即水獭在时限内最多可以看动漫的集数。
样例输入
1
2 15
3 5 5 5
5 10 1 1 1 1
样例输出
5
题目来源
7A
/* Wrong Answer at Test 1
#include<iostream>
using namespace std;
#define MAX_T 43200
int dp[MAX_T + 1]; // dp[i] 表示话费 i 秒最多可以看多少集
#define MAX_K 20
int C[MAX_K]; // 第 i 集的时长,或者前 i 集的时长总和
int main(){
int Q, N, T, i, K;
scanf("%d", &Q);
while(Q--){
scanf("%d %d", &N, &T);
memset(dp, 0, sizeof(dp));
while(N--){
scanf("%d", &K);
for(i = 1; i <= K; ++i){
scanf("%d", C + i);
C[i] += C[i - 1];
if(C[i] <= T){
dp[T] = max(dp[T], i + dp[T - C[i]]);
}
}
for(i = 1; i <= K && C[i] <= T; ++i){
dp[C[i]] = max(dp[C[i]], i);
}
}
printf("%d\n", dp[T]);
}
}
*/
/*
#include<iostream>
using namespace std;
#define MAX_T 43200
int dp[MAX_T + 1]; // dp[i] 表示话费 i 秒最多可以看多少集
#define MAX_K 20
int C[MAX_K]; // 第 i 集的时长,或者前 i 集的时长总和
int main(){
int Q, N, T, i, K;
scanf("%d", &Q);
while(Q--){
scanf("%d %d", &N, &T);
memset(dp, 0, sizeof(dp));
while(N--){
scanf("%d", &K);
for(i = 1; i <= K; ++i){
scanf("%d", C + i);
C[i] += C[i - 1];
if(C[i] <= T){
dp[T] = max(dp[T], i + dp[T - C[i]]);
}
}
for(i = 1; i <= K && C[i] <= T; ++i){
dp[C[i]] = max(dp[C[i]], i);
}
for(i = 2; i <= T ; i++){
dp[i] = max(dp[i - 1], dp[i]);
}
}
printf("%d\n", dp[T]);
}
}
*/
/* AC 312MS
#include<iostream>
using namespace std;
#define MAX_T 43200
int dp[MAX_T + 1]; // dp[i] 表示话费 i 秒最多可以看多少集
int dp2[MAX_T + 1]; // dp[i] 表示话费 i 秒最多可以看多少集
#define MAX_K 20
int C[MAX_K]; // 第 i 集的时长,或者前 i 集的时长总和
int main(){
// freopen("test.txt", "r", stdin);
int Q, N, T, i, K;
scanf("%d", &Q);
while(Q--){
scanf("%d %d", &N, &T);
memset(dp, 0, sizeof(dp));
memset(dp2, 0, sizeof(dp2));
while(N--){
scanf("%d", &K);
for(i = 1; i <= K; ++i){
scanf("%d", C + i);
C[i] += C[i - 1];
for(int j = T; j >= C[i]; j--){
dp2[j] = max(dp2[j], max(dp[j], i + dp[j - C[i]]));
}
}
for(i = 1; i <= T; ++i){
dp[i] = dp2[i];
}
// for(i = 2; i <= T ; i++){
// dp[i] = max(dp[i - 1], dp[i]);
// }
}
printf("%d\n", dp[T]);
}
}
*/
/* AC 296MS
#include<iostream>
using namespace std;
#define MAX_T 43200
int dp[MAX_T + 1]; // dp[i] 表示话费 i 秒最多可以看多少集
int dp2[MAX_T + 1]; // dp[i] 表示话费 i 秒最多可以看多少集
#define MAX_K 20
int C[MAX_K]; // 第 i 集的时长,或者前 i 集的时长总和
int main(){
// freopen("test.txt", "r", stdin);
int Q, N, T, i, K;
scanf("%d", &Q);
while(Q--){
scanf("%d %d", &N, &T);
memset(dp, 0, sizeof(int)*(T+1));
memset(dp2, 0, sizeof(int)*(T+1));
while(N--){
scanf("%d", &K);
for(i = 1; i <= K; ++i){
scanf("%d", C + i);
C[i] += C[i - 1];
for(int j = T; j >= C[i]; j--){
dp2[j] = max(dp2[j], max(dp[j], i + dp[j - C[i]]));
}
}
memcpy(dp, dp2, sizeof(int)*(T+1));
}
printf("%d\n", dp[T]);
}
}
*/
/* AC 187 MS
#include<iostream>
using namespace std;
#define MAX_T 43200
int dp[MAX_T + 1]; // dp[i] 表示话费 i 秒最多可以看多少集
int dp2[MAX_T + 1]; // dp[i] 表示话费 i 秒最多可以看多少集
#define MAX_K 20
int C[MAX_K]; // 第 i 集的时长,或者前 i 集的时长总和
int main(){
// freopen("test.txt", "r", stdin);
int Q, N, T, i, K;
scanf("%d", &Q);
while(Q--){
scanf("%d %d", &N, &T);
memset(dp, 0, sizeof(int)*(T+1));
memset(dp2, 0, sizeof(int)*(T+1));
while(N--){
scanf("%d", &K);
for(i = 1; i <= K; ++i){
scanf("%d", C + i);
C[i] += C[i - 1];
for(int j = T; j >= C[i]; j--){
dp2[j] = max(dp2[j], i + dp[j - C[i]]);
}
}
memcpy(dp, dp2, sizeof(int)*(T+1));
}
printf("%d\n", dp[T]);
}
}
*/
#include<iostream>
using namespace std;
#define MAX_T 43200
int dp[MAX_T + 1];
int dp2[MAX_T + 1];
#define MAX_K 20
int C[MAX_K];
int main(){
int Q, N, T, i, K;
scanf("%d", &Q);
while(Q--){
scanf("%d %d", &N, &T);
memset(dp, 0, sizeof(dp));
memset(dp2, 0, sizeof(dp2));
while(N--){
scanf("%d", &K);
for(i = 1; i <= K; ++i){
scanf("%d", C + i);
C[i] += C[i - 1];
for(int j = T; j >= C[i]; j--){
dp2[j] = max(dp2[j], i + dp[j - C[i]]);
}
}
memcpy(dp, dp2, sizeof(dp));
}
printf("%d\n", dp[T]);
}
}