题解 P1220 【关路灯 】
P1220 关路灯 题解
Part 1:稍微对某一些评论做下解释
1. 求前缀和以及查询的一些相关问题
inline int count(int l, int r, int i, int j) {
return (sum[l] + sum[n] - sum[r - 1]) * (d[j] - d[i]);
}
问:这里为什么是
答:我们来模拟一下前缀和就清楚了:
设
那么
如果从理论上分析:因为
2. 为什么要给f数组赋一个极大值和赋值的一些相关问题
问1:为什么赋最大值:这个是显而易见的,因为我们的大概是这样吧,这个问题有点浅显)
问2:
memset(f,127,sizeof(f);
这句话什么意思?
这不就很明确了吗?
我们知道起点
k1 = f[l][r - 1][0] + count(l - 1, r, l, r);
k2 = f[l][r - 1][1] + count(l - 1, r, r - 1, r);
f[l][r][1] = std::min(k1, k2);
//k1 k2 只是为了让代码不那么长,count函数上文写了;
向左就是反向,倒序搜索,
k1 = f[l + 1][r][0] + count(l, r + 1, l, l + 1);
k2 = f[l + 1][r][1] + count(l, r + 1, l, r);
f[l][r][0] = std::min(k1, k2);
思路到此为止,到这里就足够AC了。
part 3:下面是Show Time
自从观摩了某篇std后码风大变(源于对Dalao的崇拜)
思路上面讲的很清楚了,下面代码就不再赘述了
#include<bits/stdc++.h>
template <class T>
inline void read(T &x) {
static char c;
static bool op;
while(!isdigit(c = getchar()) && c != '-');
x = (op = c == '-')? 0 : c - '0';
while(isdigit(c = getchar()))
x = x * 10 + c - '0';
if(op) x = ~x + 1;
}
template <class T>
void putint(T x) {
static char buf[15], *tail = buf;
if(!x) putchar('0');
else {
if(x < 0) putchar('-'), x = ~x + 1;
for(; x; x /= 10) *++tail = x % 10 + '0';
for(; tail != buf; --tail) putchar(*tail);
}
putchar('\n');
}
const int N = 55;
int n, c, ans;
namespace DP {
static int d[N],sum[N];
static int f[N][N][2];
void in() {
std::memset(sum, 0, sizeof(sum));
read(n), read(c);
for(int i = 1; i <= n; ++i) {
read(d[i]), read(sum[i]);
sum[i] += sum[i - 1];
}
}
inline int count(int l, int r, int i, int j) {
return (sum[l] + sum[n] - sum[r - 1]) * (d[j] - d[i]);
}
void solve(int &ans) {
std::memset(f, 0x3f, sizeof(f));
f[c][c][0] = f[c][c][1] = 0;
for(int r = c; r <= n; ++r) {
for(int l = r - 1; l; --l) {
int k1, k2;
k1 = f[l + 1][r][0] + count(l, r + 1, l, l + 1);
k2 = f[l + 1][r][1] + count(l, r + 1, l, r);
f[l][r][0] = std::min(k1, k2);
k1 = f[l][r - 1][0] + count(l - 1, r, l, r);
k2 = f[l][r - 1][1] + count(l - 1, r, r - 1, r);
f[l][r][1] = std::min(k1, k2);
}
}
ans = std::min(f[1][n][1], f[1][n][0]);
}
}
using DP::in;
using DP::solve;
int main() {
in();
solve(ans);
putint(ans);
return 0;
}
End
走过路过点个赞呗QAQ