Codeforces Round #186 (Div. 2) Problem D 动态规划
题意:一条路上有n(n<=300)个洞,m(m<=100000)个公司,第i个公司可以修复连续区间 Li ~ Ri 内的洞,花费为Vi。问至少修复k个洞,最小花费是多少?
分析:先处理出一条线段覆盖 [l, r],并且右端点恰好在r上的最小代价V[l, r],
然后dp(i, j) 表示前j个点,修复i个的最小代价,dp[i, j] = min ( dp[i, j-1], dp[i-r, j-r] + V[j-r+1, j] )
const int M = 305; LL dp[M][M], a[M][M], ans; int n, m, k; int main(){ #ifndef ONLINE_JUDGE freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); #endif scanf("%d%d%d", &n, &m, &k); memset(a, 1, sizeof a); memset(dp, 1, sizeof dp); ans = dp[0][0]; FOE(i, 0, n) dp[0][i] = 0; FOR(i, 0, m){ int l, r; LL v; scanf("%d%d%I64d", &l, &r, &v); int t = max(r-k+1, l); FOE(j, t, r) checkmin(a[j][r], v); } FOE(j, 1, n){ int t = min(j, k); FOE(i, 1, t){ dp[i][j] = dp[i][j-1]; FOE(r, 1, i) checkmin(dp[i][j], dp[i-r][j-r] + a[j-r+1][j]); } } if(ans == dp[k][n]) ans = -1; else ans = dp[k][n]; printf("%I64d\n", ans); return 0; }