2018.10.21 bzoj1742: Grazing on the Run 邊跑邊吃草(區間dp)
阿新 • • 發佈:2018-12-16
傳送門 區間dp入門題。
可以想到當前吃掉的草一定是一個區間(因為經過的草一定會吃掉)。 然後最後一定會停在左端點或者右端點。 表示已經吃了的草,最後停在左/右端點。 利用費用提前計算的思想轉移就行了。 程式碼:
#include<bits/stdc++.h>
#define N 1005
#define ll long long
using namespace std;
ll f[N][N][2],l,pos[N];
int n;
inline int read(){
int ans=0;
char ch=getchar();
while(!isdigit(ch))ch=getchar();
while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch^48),ch=getchar();
return ans;
}
int main(){
n=read(),l=read();
for(int i=1;i<=n;++i)pos[i]=read();
pos[++n]=l;
sort(pos+1,pos+n+1);
for(int i=1;i<=n;++i)f[i][i][0]=f[i][i][1]=abs(l-pos[ i])*n;
for(int len=2;len<=n;++len){
for(int i=1;i<=n-len+1;++i){
int j=i+len-1;
f[i][j][0]=min(f[i+1][j][0]+(n-len+1)*(pos[i+1]-pos[i]),f[i+1][j][1]+(n-len+1)*(pos[j]-pos[i]));
f[i][j][1]=min(f[i][j-1][0]+(n-len+1)*(pos[j]-pos[i]),f[i][j-1][1]+(n-len+1)*(pos[j]-pos[j-1]));
}
}
cout<< min(f[1][n][0],f[1][n][1]);
return 0;
}