题目大意:
给出一个长为 N N N的序列,起点在 0 0 0,有 K K K种方式,每种可以花费 w i w_i wi然后从某个位置 i i i走到位置 i + C i i+C_i i+Ci,如果走到 i i i用的是 j j j方式,那么当你下一次走的时候方式不是 j j j时,切换方式需要花费 W W W,有 Q Q Q个限制 a i , b i a_i,b_i ai,bi,表示不能使用方式 a i a_i ai经过位置 b i b_i bi,问走到位置 N N N的最少花费。
N
<
=
500
,
K
<
=
100
N<=500,K<=100
N<=500,K<=100
Q
<
=
50000
,
W
<
=
1
e
7
Q<=50000,W<=1e7
Q<=50000,W<=1e7
分析:
设
f
[
i
]
[
j
]
f[i][j]
f[i][j]表示走到位置
i
i
i时方式为
j
j
j的最少花费,
f
[
i
]
[
j
]
=
m
i
n
(
f
[
i
−
C
k
]
[
k
]
+
w
i
+
(
(
k
=
j
)
?
0
:
W
)
)
f[i][j]=min(f[i-C_k][k]+w_i+((k=j)? 0:W))
f[i][j]=min(f[i−Ck][k]+wi+((k=j)?0:W))
时间复杂度:
O
(
N
K
2
)
O(NK^2)
O(NK2)
代码:
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <queue>
#include <cmath>
#define inf 0x7fffffff
#define N 505
#define M 105
using namespace std;
typedef long long ll;
struct Node { int len; ll cost; }a[M];
int sum[M][N], n, m, Q;
ll f[N][N], W;
int read(int &x)
{
int f = 1; x = 0; char s = getchar();
while (s < '0' || s > '9') { if (s == '-') f = -1; s = getchar(); }
while (s >= '0' && s <= '9') { x = x * 10 + (s - '0'); s = getchar(); }
x = x * f;
}
void write(ll x)
{
if (x > 9) write(x / 10);
putchar(x % 10 + '0');
}
int main()
{
freopen("qinggong.in", "r", stdin);
freopen("qinggong.out", "w", stdout);
read(n); read(m); ++n; scanf("%lld", &W);
for (int i = 1; i <= m; i++) read(a[i].len), scanf("%lld", &a[i].cost);
read(Q);
while (Q--)
{
int x, y; read(x); read(y);
sum[y][x + 1] = 1;
}
for (int i = 1; i <= m; i++)
for (int j = 1; j <= n; j++) sum[i][j] = sum[i][j] + sum[i][j - 1];
for (int i = 2; i <= n; i++)
for (int j = 1; j <= m; j++) f[i][j] = inf;
for (int i = 2; i <= n; i++)
for (int j = 1; j <= m; j++)
if (i > a[j].len)
if (sum[j][i] - sum[j][i - a[j].len - 1] == 0)
{
for (int k = 1; k <= m; k++)
if (k != j) f[i][j] = min(f[i][j], f[i - a[j].len][k] + W + a[j].cost);
else f[i][j] = min(f[i][j], f[i - a[j].len][k] + a[j].cost);
}
ll ans = inf;
for (int i = 1; i <= m; i++) ans = min(ans, f[n][i]);
if (ans == inf) printf("-1\n");
else { write(ans); printf("\n"); }
return 0;
}