P3035 [USACO11DEC]Umbrellas for Cows S(DP)
阿新 • • 發佈:2020-09-06
Solution
很容易看出本題是用dp解的,所以我們設 \(f[i]\) 表示前 \(i\) 個覆蓋所需的最小价值。
易得: \(f[i]=\min(f[i],f[j-1]+cost[a[i]-a[j]+1])\)
其中 \(a[i]\) 為第 \(i\) 個點的位置, \(cost[i]\) 表示長度為 \(i\) 的線段的價格
但是,因為長度越長的線段價格不一定越高並且長度長的可以覆蓋短的,所以我們在 $cost[a[i]-a[j]+1] $ ~ \(cost[m]\) 選一個最小的即可,為了防超時,可預處理一個字尾最小值陣列。
程式碼
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int N=200005; int n,m,f[N],cost[N],a[N],v[N]; inline int read(){ int x=0,f=1; char ch=getchar(); while(!isdigit(ch)){if(ch=='-') f=-1;ch=getchar();} while(isdigit(ch)){x=x*10+(ch^48);ch=getchar();} return x*f; } int main(){ n=read();m=read(); memset(f,63,sizeof(f));f[0]=0; for(int i=1;i<=n;i++) a[i]=read(); sort(a+1,a+n+1); for(int i=1;i<=m;i++) v[i]=read(); v[0]=1<<30,cost[m+1]=1<<30; for(int i=m;i>=0;i--) cost[i]=min(v[i],cost[i+1]); for(int i=1;i<=n;i++) for(int j=i;j;j--) f[i]=min(f[i],f[j-1]+cost[a[i]-a[j]+1]); printf("%d\n",f[n]); return 0; }