项目安排[动态规划]
小明每天都在開源社區(qū)上做項目,假設(shè)每天他都有很多項目可以選,其中每個項目都有一個開始時間和截止時間,假設(shè)做完每個項目后,拿到報酬都是不同的。由于小明馬上就要碩士畢業(yè)了,面臨著買房、買車、給女友買各種包包的鴨梨,但是他的錢包卻空空如也,他需要足夠的money來充實錢包。萬能的網(wǎng)友麻煩你來幫幫小明,如何在最短時間內(nèi)安排自己手中的項目才能保證賺錢最多(注意:做項目的時候,項目不能并行,即兩個項目之間不能有時間重疊,但是一個項目剛結(jié)束,就可以立即做另一個項目,即項目起止時間點可以重疊)。
?
輸入可能包含多個測試樣例。
對于每個測試案例,輸入的第一行是一個整數(shù)n(1<=n<=10000):代表小明手中的項目個數(shù)。
接下來共有n行,每行有3個整數(shù)st、ed、val,分別表示項目的開始、截至?xí)r間和項目的報酬,相鄰兩數(shù)之間用空格隔開。
st、ed、value取值均在32位有符號整數(shù)(int)的范圍內(nèi),輸入數(shù)據(jù)保證所有數(shù)據(jù)的value總和也在int范圍內(nèi)。
?
對應(yīng)每個測試案例,輸出小明可以獲得的最大報酬。
?
解題思路:
動態(tài)規(guī)劃題
可以按照01背包思路解決。不同之處在于:01背包中是順序無關(guān)的
這里按結(jié)束的時間先排序。(也可以按開始時間排序,遍歷的次序需要顛倒一下)
因為是最短時間,所以按結(jié)束時間排序, 假設(shè)第i個任務(wù)的去留情況:
1、如果不要第i個任務(wù),則 dp[i]=dp[i-1]; ?
2、添加第i個任務(wù),現(xiàn)在主要是根據(jù)時間關(guān)系判斷添加第i個任務(wù)時,前面有幾個任務(wù),
動態(tài)關(guān)系: dp[i]=max(dp[i-1],dp[k]+value[i]), 主要是在第i個任務(wù)時,找到k的值。
#include <stdio.h> #include <algorithm> using namespace std; int n; class P{ public:int st,ed,value; }; P p[10001]; int dp[10001]; //dp[i]安排前i個項目,最多能到得到的最大value bool cmp(const P & p1, const P & p2){return p1.ed < p2.ed; }int main(){int n, i, j;//freopen("in.txt", "r", stdin);while(scanf("%d", &n) != EOF){for(i=1; i<=n; i++){scanf("%d %d %d", &p[i].st, &p[i].ed, &p[i].value);dp[i] = 0;}sort(p+1, p+n+1, cmp); //按結(jié)束時間排序是重點dp[0] = 0;for(i=1; i<=n; i++){//查找最的j,可滿足當(dāng)前的i。都不滿足就j=0for(j=i-1; j>0; j--){if(p[i].st >= p[j].ed)break;}dp[i] = dp[j] + p[i].value;if(dp[i] < dp[i-1])dp[i] = dp[i-1];}printf("%d\n",dp[n]);}return 0; }
總結(jié)
以上是生活随笔為你收集整理的项目安排[动态规划]的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Maximum Product Suba
- 下一篇: 买饭问题