分析
d
p
[
i
]
[
j
]
[
k
]
dp[i][j][k]
dp[i][j][k]代表区间
i
i
i,
j
j
j的灯已经全部关闭时老王在
i
i
i处
(
k
=
=
0
)
(k==0)
(k==0)或
j
j
j处
(
k
=
=
1
)
(k==1)
(k==1)的时间点已经浪费的电量
那么
dp[i][j][0]=min(dp[i+1][j][0]+val(i,i+1,i,j+1),dp[i+1][j][1]+val(i,j,i,j+1)),
dp[i][j][1]=min(dp[i][j-1][0]+val(i,j,i-1,j),dp[i][j-1][1]+val(j-1,j,i-1,j));
问题是val怎么求
v
a
l
(
i
,
j
)
=
(
l
o
c
j
−
l
o
c
i
)
×
(
∑
1
i
−
1
a
[
i
]
+
∑
j
+
1
n
a
[
i
]
)
val(i,j)=(loc_j-loc_i)\times (\sum_{1}^{i-1}a[i]+\sum_{j+1}^{n}a[i])
val(i,j)=(locj−loci)×(1∑i−1a[i]+j+1∑na[i])
代码
#include <cstdio>
#include <cctype>
#include <cstring>
#define rr register
#define val(l,r,L,R) (loc[r]-loc[l])*(s[L]+s[n]-s[R-1])
using namespace std;
inline signed iut(){
rr int ans=0,f=1; rr char c=getchar();
while (!isdigit(c)) f=(c==45)?-f:f,c=getchar();
while (isdigit(c)) ans=ans*10+(c-48),c=getchar();
return ans;
}
int n=iut(),c=iut(),loc[51],s[51],dp[51][51][2];
inline signed min(int a,int b){return a<b?a:b;}
signed main(){
memset(dp,127/3,sizeof(dp));
for (rr int i=1;i<=n;++i){
rr int a=iut(),b=iut();
loc[i]=a,s[i]=s[i-1]+b;
}
dp[c][c][0]=dp[c][c][1]=0;
for (rr int j=c;j<=n;++j)
for (rr int i=j-1;i;--i)
dp[i][j][0]=min(dp[i+1][j][0]+val(i,i+1,i,j+1),dp[i+1][j][1]+val(i,j,i,j+1)),
dp[i][j][1]=min(dp[i][j-1][0]+val(i,j,i-1,j),dp[i][j-1][1]+val(j-1,j,i-1,j));
printf("%d",min(dp[1][n][0],dp[1][n][1]));
return 0;
}