题目:
时间限制:1000ms 内存限制:131072kb
题目描述
最近学校大检查,要求上课认真听讲,这让浪哥很是烦恼,因为这样他就不能上课刷题了。但经过不懈的观察,他发现领导检查是有一定的规律的。不妨把每层楼的教室看成一排,从 11 到 nn 标号,领导每检查完一个教室,就会从相邻的一个或两个教室中选择一个继续检查,一个教室可能被检查不止一次。
已知时刻 00 领导在 11 号教室,从 ii 号教室走到 i+1i+1 号教室需要 titi 时间,从 i+1i+1 号教室走到 ii 号教室也需要 titi 时间 (i=1,2,⋯,n−1)(i=1,2,⋯,n−1),检查一个教室的时间极短可忽略不计,放学时刻为 mm 。
浪哥想要知道,放学之前(包括 mm )的哪些时刻,领导是不可能检查到他所在的 nn 号教室的。
输入
第一行包含一个正整数 TT ,表示有 TT 组测试数据。
接下来依次给出每组测试数据。对于每组测试数据:
第一行包含两个正整数 nn 和 mm。
第二行包含 n−1n−1个正整数 t1,t2,⋯,tn−1t1,t2,⋯,tn−1。
1≤T≤200,2≤n≤100,1≤m≤500,1≤ti≤m1≤T≤200,2≤n≤100,1≤m≤500,1≤ti≤m
输出
对于每组数据输出一行,包含一些正整数,按升序给出,表示 nn 号教室不可能被检查的时刻。
对于本题,输出中在一行的每个整数之间用恰好一个空格隔开,不能有其他额外空格。
输入样例
1
3 10
2 3
输出样例
1 2 3 4 6 7 8 10
样例解释
在放学前,领导有两种不同的检查方式会检查到 3 号教室,分别是 1 -> 2 -> 3 和 1 -> 2 -> 1 -> 2 -> 3 ,其中到达 3 号教室的时刻分别为 5 和 9 。
题解:
至少要到n, 所以可以先记下这个时间s, 如果s在时限内, 用母函数确定剩下的可达时间
往返所需时间是二倍, 以这个为单位dp
/*
Author: YY & 8023
Result: AC Submission_id: 226762
Created at: Sun Dec 18 2016 15:22:29 GMT+0800 (CST)
Problem_id: 587 Time: 9 Memory: 2784
*/
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
int n, m, vis[505];
int a[105];
int main() {
//freopen("in.txt", "r", stdin);
cin.tie(0);
cin.sync_with_stdio(false);
int t;
scanf("%d", &t);
while (t--) {
scanf("%d%d", &n, &m);
memset(vis, 0, sizeof(vis));
int s = 0;
for (int i = 1; i < n; ++i) {
scanf("%d", &a[i]);
s += a[i];
a[i] *= 2;
if (s > m) break;
}
if (s <= m) {
vis[s] = 1;
//int v = m - s;
for (int i = 1; i < n; ++i) {
for (int j = s; j < m; ++j)
for (int k = a[i]; k + j <= m; k += a[i]) {
if(!vis[k + j]) vis[k + j] = vis[j];//注意这里只有k + j这个时间点没确定才能赋值
}
}
}
int flag = 0;
for (int i = 1; i <= m; ++i) {
if (!vis[i]) {
if (flag) printf(" ");
else flag = 1;
printf("%d", i);
}
}
puts("");
}
return 0;
}