1. 程式人生 > 實用技巧 >《洛谷P3035 [USACO11DEC]Umbrellas for Cows S》

《洛谷P3035 [USACO11DEC]Umbrellas for Cows S》

第一眼就覺得是個DP。一開始想的揹包列舉對應長度時的最小代價。

但是這樣複雜度是N*M,顯然會T。

正解:不需要去考慮湊成長度的最優代價。

用dp[i]來表示到把到i包括i的牛全覆蓋掉的最小代價。

那麼對於每一個i,我們去列舉轉移的位置j,這樣最優的方案裡會包括上最優的組合法(包括重複選同一個)

那麼轉移很明顯,主要的是,可能更大的長度它的價值更小,且長度更大,那麼更新為它即可。

// Author: levil
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int
,int> pii; const int N = 5e3+5; const int M = 1e5+5; const LL Mod = 1e9+7; #define rg register #define pi acos(-1) #define INF 1e18 #define CT0 cin.tie(0),cout.tie(0) #define IO ios::sync_with_stdio(false) #define dbg(ax) cout << "now this num is " << ax << endl; namespace FASTIO{ inline
int read(){ int x = 0,f = 1;char c = getchar(); while(c < '0' || c > '9'){if(c == '-') f = -1;c = getchar();} while(c >= '0' && c <= '9'){x = (x<<1)+(x<<3)+(c^48);c = getchar();} return x*f; } void print(int x){ if(x < 0
){x = -x;putchar('-');} if(x > 9) print(x/10); putchar(x%10+'0'); } } using namespace FASTIO; void FRE(){ /*freopen("data1.in","r",stdin); freopen("date1.out","w",stdout);*/} //P3035 [USACO11DEC]Umbrellas for Cows S LL x[N],c[M]; LL dp[N];//把到第i只牛覆蓋進去的最小代價 int main() { int n,m;n = read(),m = read(); for(rg int i = 1;i <= n;++i) x[i] = read(); fill(dp,dp+N-1,INF); sort(x+1,x+n+1); for(rg int i = 1;i <= m;++i) c[i] = read(); for(rg int i = m-1;i >= 1;--i) c[i] = min(c[i],c[i+1]); dp[0] = 0; dp[1] = c[1]; for(rg int i = 2;i <= n;++i) { int ma = x[i]-x[i-1]; for(rg int j = 1;j <= i;++j) dp[i] = min(dp[i],dp[j-1]+c[x[i]-x[j]+1]); } printf("%lld\n",dp[n]); system("pause"); return 0; } /* 3 4 2 4 5 3 3 5 7 15 18 */
View Code