NYOJ 720 DP+二分
阿新 • • 發佈:2017-07-01
ref main 測試 style bool splay 兩個 pla con
項目安排
時間限制:3000 ms | 內存限制:65535 KB 難度:4- 描述
- 小明每天都在開源社區上做項目,假設每天他都有很多項目可以選,其中每個項目都有一個開始時間和截止時間,假設做完每個項目後,拿到報酬都是不同的。由於小明馬上就要碩士畢業了,面臨著買房、買車、給女友買各種包包的鴨梨,但是他的錢包卻空空如也,他需要足夠的money來充實錢包。萬能的網友麻煩你來幫幫小明,如何在最短時間內安排自己手中的項目才能保證賺錢最多(註意:做項目的時候,項目不能並行,即兩個項目之間不能有時間重疊,但是一個項目剛結束,就可以立即做另一個項目,即項目起止時間點可以重疊)。
- 輸入
- 輸入可能包含多個測試樣例。
對於每個測試案例,輸入的第一行是一個整數n(1<=n<=5000):代表小明手中的項目個數。
接下來共有n行,每行有3個整數st、ed、val,分別表示項目的開始、截至時間和項目的報酬,相鄰兩數之間用空格隔開。
st、ed、value取值均在32位有符號整數(int)的範圍內,輸入數據保證所有數據的value總和也在int範圍內。 - 輸出
- 對應每個測試案例,輸出小明可以獲得的最大報酬。
- 樣例輸入
-
3 1 3 6 4 8 9 2 5 16 4 1 14 10 5 20 15 15 20 8 18 22 12
- 樣例輸出
-
16 22
- 提示
- 上傳時數據加強,項目起始時間和終止時間可能相同(其他oj可能無此情況)
- 來源
- 網易有道2013年校園招聘面試二面試題
- 上傳者
- 勿念情
- 感覺N^2也可以過啊,T了,後來用的二分A掉,二分寫炸了調了半天最後發現排序小標寫錯了,ccc
- dp[i]表示前i個項目可獲得的最大價值,則dp[i]=max(dp[i-1],solve(i-1)+P[i].val)
- solve()就是我們要找的在滿足與目標項目不交叉的情況下的最大價值。
- 由於要二分查找顯然dp[]數組必須有序,所以dp[i]表示前i個項目可獲得的最大價值,這樣的話二分找到的某個合法項目之前的項目顯然也在目標項目之前且不交叉。
- #include<bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f;
struct node
{
int st,ed,val;
bool operator<(const node &c)const{
if(st==c.st&&ed==c.ed) return val>c.val;
if(ed==c.ed) return st<c.st;
return ed<c.ed;
}
}P[5005];
int dp[5005];
int solve(int t)
{
if(!t) return 0;
int l=1,r=t,mid,i,j,k,ans=0;
while(l<r){
mid=r-(r-l)/2;
if(P[mid].ed<=P[t+1].st){
l=mid;
}
else{
r=mid-1;
}
}
if(l==r&&P[l].ed<=P[t+1].st) return dp[l];
return 0;
}
int main()
{
int N,i,j,k;
node a,b;
while(cin>>N){
for(i=1;i<=N;++i){
scanf("%d%d%d",&P[i].st,&P[i].ed,&P[i].val);
}
sort(P+1,P+N+1);
for(i=1;i<=N;++i){
dp[i]=max(solve(i-1)+P[i].val,dp[i-1]);
}
printf("%d\n",dp[N]);
}
return 0;
}
NYOJ 720 DP+二分