第一眼就觉得是个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 */