sgu183:Painting the balls(dp+优化)
2014-12-28 13:29
387 查看
题意:
在n(n<=10000)个球中,给若干个球涂色,每个球涂色的代价为Ci,使得任意连续m(m<=100)个球中有至少两个球被涂了色且总代价最小。
分析:
这个dp有点难想...
由于每次涂色的时候只与前两个涂色的球有关,因此设f[i][j]为倒数第二个涂色的为第i个球,最后一个涂色的球为第j个球的最小代价。
f[i][j]=min{f[k][i]}+c[j],由于区间[j-m,j-1]需要被覆盖,所以j-m<=k<i<j。
sgu内存限制只能滚动数组...
时间复杂度为O(n*m*m),话说应该过不了的,但竟然218ms过了...
其实还可以优化:
f[i][j]=min{f[k][i]}+c[j],j-m<=k<i<j
f[i][j+1]=min{f[k][i]}+c[j+1],j-m+1<=k<i<j
我们可以发现f[i][j]与f[i][j+1]的搜索重叠部分为min{f[k][i]},j-m+1<=k<i<j
设g[i][j]=min{f[k][j]},那么g[i][j]=min{g[i][j+1],f[j-m][i]}。
时间复杂度O(n*m),31ms...
在n(n<=10000)个球中,给若干个球涂色,每个球涂色的代价为Ci,使得任意连续m(m<=100)个球中有至少两个球被涂了色且总代价最小。
分析:
这个dp有点难想...
由于每次涂色的时候只与前两个涂色的球有关,因此设f[i][j]为倒数第二个涂色的为第i个球,最后一个涂色的球为第j个球的最小代价。
f[i][j]=min{f[k][i]}+c[j],由于区间[j-m,j-1]需要被覆盖,所以j-m<=k<i<j。
sgu内存限制只能滚动数组...
时间复杂度为O(n*m*m),话说应该过不了的,但竟然218ms过了...
/* f[i][j]=min{f[k][i]}+c[j],j-m<=k<i<j; */ #include <cstdio> #include <iostream> #include <algorithm> using namespace std; const int MAXN = 10009, MAXM = 109, INF = 1e9; int n, m; int c[MAXN]; int f[MAXM][MAXM]; int main() { cin >> n >> m; for(int i = 1; i <= n; ++i) { cin >> c[i]; f[0][i] = c[i]; } for(int i = 1; i < n; ++i) for(int j = i+1; j < i+m && j <= n; ++j) { int minimum = INF; for(int k = max(0, j-m); k < i; ++k) minimum = min(minimum, f[k%MAXM][i%MAXM]); f[i%MAXM][j%MAXM] = minimum+c[j]; } int ans = INF; for(int i = n-m+1; i < n; ++i) for(int j = i+1; j <= n; ++j) ans = min(ans, f[i%MAXM][j%MAXM]); cout << ans << endl; return 0; }
其实还可以优化:
f[i][j]=min{f[k][i]}+c[j],j-m<=k<i<j
f[i][j+1]=min{f[k][i]}+c[j+1],j-m+1<=k<i<j
我们可以发现f[i][j]与f[i][j+1]的搜索重叠部分为min{f[k][i]},j-m+1<=k<i<j
设g[i][j]=min{f[k][j]},那么g[i][j]=min{g[i][j+1],f[j-m][i]}。
时间复杂度O(n*m),31ms...
/* f[i][j]=min{f[k][i]}+c[j],j-m<=k<i<j; g[i][j]=min{f[k][i]},j-m<=k<i<j g[i][j+1]=min{f[k][i]},j-m+1<=k<i<j g[i][j]=min{g[i][j+1],f[j-m][i]}; */ #include <cstdio> #include <iostream> #include <algorithm> using namespace std; const int MAXN = 10009, MAXM = 109, INF = 1e9; int n, m; int c[MAXN]; int f[MAXM][MAXM]; int mod[MAXN+MAXM]; int main() { cin >> n >> m; for(int i = 1; i <= n; ++i) cin >> c[i]; for(int i = 1; i <= n+m; ++i) mod[i] = i%MAXM; for(int i = 1; i < m; ++i) for(int j = i+1; j <= m; ++j) f[i][j] = c[i]+c[j]; for(int i = 1; i < n; ++i) { int tmp = INF; for(int j = i+m-1; j > i; --j) { if(j <= m) break; tmp = min(tmp, f[mod[j-m]][mod[i]]); f[mod[i]][mod[j]] = tmp+c[j]; } } int ans = INF; for(int i = n-m+1; i < n; ++i) for(int j = i+1; j <= n; ++j) ans = min(ans, f[mod[i]][mod[j]]); cout << ans << endl; return 0; }
相关文章推荐
- SGU183 Painting the balls(DP+优化)
- SGU 183 Painting the balls (DP优化)
- sgu183 Painting the balls_dp
- SGU 183 Painting the balls(DP)
- Painting the balls SGU - 183
- HDU 3698 Let the light guide us 线段树求区间优化dp
- SGU 407-Number of Paths in the Empire【DP】
- Light OJ 1317 Throwing Balls into the Baskets 概率DP
- HDU2227 - Find the nondecreasing subsequences(线段树优化DP)
- SGU 365 Ships of the Desert dp
- dp优化专辑 I - Cut the Tree [树形dp]
- Poj 3017 Cut the Sequence (DP,单调队列优化,数据结构优化)
- poj 3017 Cut the Sequence(dp单调队列优化)
- hdu 3698 Let the light guide us(线段树优化&简单DP)
- CF 319C - Kalila and Dimna in the Logging Industry 斜率优化DP
- POJ 3017 Cut the Sequence (单调队列优化DP)
- SGU 365 Ships of the Desert 简单数位dp
- POJ--3017--Cut the Sequence--DP优化
- poj3017 Cut the Sequence 单调队列优化dp 好题!
- POJ 2373 (Dividing the Path)单调队列优化DP