题解
- 数据这么小,各位大爷肯定都会做吧
- 考虑dp,设f[i][j]为走到第i个木桩,现在是用第j中轻功的最小时间
- 状态转移方程显然
- 那么,考虑一下题目的条件,有一些限制木桩不能用某些轻功经过
- 可以设g[i][j]为用j轻功到i有多少个没有的经过的木桩
- 剩下的平平常常都能A吧
代码
1 #include <cstdio>
2 #include <iostream>
3 #include <cstring>
4 using namespace std;
5 const long long inf=0x3f3f3f3f3f3f;
6 int n,k,w,a[510],v[510],Q,g[510][110];
7 long long f[510][110],ans;
8 int main()
9 {
10 //freopen("qinggong.in","r",stdin);
11 //freopen("qinggong.out","w",stdout);
12 scanf("%d%d%d",&n,&k,&w);
13 for (int i=1;i<=k;i++) scanf("%d%d",&a[i],&v[i]);
14 scanf("%d",&Q);
15 for (int i=1,x,y;i<=Q;i++) scanf("%d%d",&x,&y),g[x][y]=1;
16 for (int i=1;i<=k;i++)
17 for (int j=1;j<=n;j++)
18 g[j][i]+=g[j-1][i];
19 memset(f,125,sizeof(f));
20 for (int i=1;i<=k;i++) f[0][i]=0;
21 for (int i=0;i<=n;i++)
22 for (int j=1;j<=k;j++)
23 for (int z=1;z<=k;z++)
24 if (i+a[z]<=n&&(g[i+a[z]][z]-g[i][z]==0))
25 {
26 if (j==z) f[i+a[z]][z]=min(f[i+a[z]][z],f[i][j]+v[z]);
27 else f[i+a[z]][z]=min(f[i+a[z]][z],f[i][j]+v[z]+w);
28 }
29 ans=inf;
30 for (int i=1;i<=k;i++) ans=min(ans,f[n][i]);
31 printf("%lld",ans==inf?-1:ans);
32 }