bzoj1617 / P2904 [USACO08MAR]跨河River Crossing
P2904 [USACO08MAR]跨河River Crossing
显然的dp
设$f[i]$表示运走$i$头奶牛,木筏停在未过河奶牛一侧所用的最小代价
$s[i]$表示一次运$i$头奶牛到对面的代价
我们枚举上次运走了$j$头,显然$f[i]=min(f[i],f[i-j]+s[j]+s[0])$(注意自己要划回来)
最后不用划回来,减去一个$s[0]$即可
end.
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #define re register 5 using namespace std; 6 int min(int a,int b){return a<b?a:b;} 7 #define N 2502 8 int n,a,f[N],s[N]; 9 int main(){ 10 memset(f,127,sizeof(f)); f[0]=0; 11 scanf("%d%d",&n,&s[0]); 12 for(re int i=1;i<=n;++i) scanf("%d",&a),s[i]=s[i-1]+a; 13 for(re int i=1;i<=n;++i) 14 for(re int j=0;j<i;++j) 15 f[i]=min(f[i],f[j]+s[i-j]+s[0]); 16 printf("%d",f[n]-s[0]);//最后不用划回来 17 return 0; 18 }