描述html
牛在飼料槽前排好了隊。飼料槽依次用1到N(1≤N≤2000) 編號。天天晚上,一頭幸運的牛根據約翰的規則,吃其中一些槽裏的飼料。node
約翰提供 N個區間的清單。一個區間是一對整數 l,r(1≤l≤r≤N),表示一些連續的飼料槽,好比 1-3,7-8,3−4 等等。牛能夠任意選擇區間,可是牛選擇的區間不能有重疊。c++
固然,牛但願本身可以吃得越多越好。給出一些區間,幫助這隻牛找一些區間,使它能吃到最多的東西。markdown
在上面的例子中,1-3 和 3−4 是重疊的;聰明的牛選擇1−3,7−8 ,這樣能夠吃到 5個槽裏的東西。函數
輸入flex
第一行,整數 N(1≤N≤2000)。spa
第 2 到 N+1 行,每行兩個整數,表示一個區間,較小的端點在前面。code
輸出htm
僅一個整數,表示最多能吃到多少個槽裏的食物。blog
輸入樣例 1
3 1 3 7 8 3 4
輸出樣例 1
5
看完題目,咱們會感受很簡單,但又無從下手。由於這裏包含了左邊界和右邊界,因此咱們先定義一個結構體。
struct node
{
long long b,c;
}a[100010];
而後對它進行排序,或許會有點思路
sort(a+1,a+1+n);//排序,爲以後dp作準備
由於這是結構體的排序,因此咱們須要自定義一個排序函數
bool cmp( node x, node y)//自定義排序方法 { if(x.c!=y.c) return x.c<y.c; return x.b<y.b; }
sort(a+1,a+1+n,cmp);//排序,爲以後dp作準備
而後便開始dp
ans=dp[1]=a[1].c-a[1].b+1;//這有個小細節,就是需+1後結果才正確 for(long long i=2;i<=n;i++) { dp[i]=a[i].c-a[i].b+1;//需+1 for(long long j=1;j<=i-1;j++) { if(a[j].c<a[i].b)//若是後一個的左邊界比前一個的右邊界大 { dp[i]=max(dp[i],dp[j]+(a[i].c-a[i].b+1));//dp求最大值 ,一樣需+1 } } ans=max(ans,dp[i]);//取最大值 }
因而,代碼便出來了
#include<bits/stdc++.h> using namespace std; long long n,ans; struct node { long long b,c; }a[100010]; bool cmp( node x, node y)//自定義排序方法 { if(x.c!=y.c) return x.c<y.c; return x.b<y.b; } long long dp[100010]; int main() { cin>>n; for(long long i=1;i<=n;i++) { cin>>a[i].b>>a[i].c; } sort(a+1,a+1+n,cmp);//排序,爲以後dp作準備 for(long long i=1;i<=n;i++) { cout<<a[i].b<<' '<<a[i].c<<endl; } ans=dp[1]=a[1].c-a[1].b+1;//這有個小細節,就是需+1後結果才正確 for(long long i=2;i<=n;i++) { dp[i]=a[i].c-a[i].b+1; for(long long j=1;j<=i-1;j++) { if(a[j].c<a[i].b)//若是後一個的左邊界比前一個的右邊界大 { dp[i]=max(dp[i],dp[j]+(a[i].c-a[i].b+1));//dp求最大值 } } ans=max(ans,dp[i]);//取最大值 } cout<<ans; return 0; }
這是一道很好的dp題,可使咱們對dp的理解更深入。因此,快去作一作吧!