LP1052
可以看到本题的l很大,不能作为数组索引量。一般情况下考虑两种做法,一种是转变思考状态的方法,把l转移到数组元素值上,另一种离散化。
本题用后者。
首先列出状态转移方程,i指的是线段上的坐标。
本题代码需要注意,线性离散化的通常实现方法。
#include
#include
#include
#include
#include
#define _for(i,a,b) for(int i = (a); i<(b); i++)
#define _rep(i,a,b) for(int i = (a); i<=(b); i++)
using namespace std;
const int maxm = 100 + 10;
const int maxl = 2000 + 100; // 2*t*m
int l, s, t, m, stone[maxm], pos[maxm], d[maxl];
int main() {
scanf("%d%d%d%d", &l, &s, &t, &m);
_rep(i, 1, m) scanf("%d", &stone[i]);
sort(stone + 1, stone + m + 1); // 注意,实际比赛中,这种对数据的简单操作往往十分重要
// 离散化
_rep(i, 1, m)
if (stone[i] - stone[i - 1] > t) pos[i] = pos[i - 1] + t + (stone[i] - stone[i - 1]) % t;
else pos[i] = pos[i - 1] + stone[i] - stone[i - 1];
if (l - stone[m] > t) l = pos[m] + t + (l - stone[m]) % t;
else l = pos[m] + l - stone[m];
// 递推
int stoneindex = 1;
_for(i, 1, l + t) {
int add = 0;
if (pos[stoneindex] == i) { add = 1; stoneindex++; }
d[i] = maxm;
_rep(k, s, t)
if (i - k >= 0)
d[i] = min(d[i], d[i - k] + add);
}
// 找解,输出
int ans = maxm;
_for(i, l, l + t) ans = min(ans, d[i]);
printf("%d\n", ans);
return 0;
}