2023年8月1日发(作者:)

经典动态规划----饥饿的⽜(hunger)饥饿的⽜(hunger)Description⽜在饲料槽前排好了队。饲料槽依次⽤1到N(1<=N<=2000)编号。每天晚上,⼀头幸运的⽜根据约翰的规则,吃其中⼀些槽⾥的饲料。约翰提供B个区间的清单。⼀个区间是⼀对整数start-end,1<=start<=end<=N,表⽰⼀些连续的饲料槽,⽐如1-3,7-8,3-4等等。⽜可以任意选择区间,但是⽜选择的区间不能有重叠。当然,⽜希望⾃⼰能够吃得越多越好。给出⼀些区间,帮助这只⽜找⼀些区间,使它能吃到最多的东西。在上⾯的例⼦中,1-3和3-4是重叠的;聪明的⽜选择{1-3,7-8},这样可以吃到5个槽⾥的东西。Input第⼀⾏,整数B(1<=B<=1000)第2到B+1⾏,每⾏两个整数,表⽰⼀个区间,较⼩的端点在前⾯。Output仅⼀个整数,表⽰最多能吃到多少个槽⾥的⾷物。Sample Input 131 37 83 4Sample Output 15问题虽然看着⽐较复杂,但可以转换成⼀个简单的01背包问题,动态⽅程dp[j] = max(dp[j],dp[s[i].x - 1] + s[i].total)这⾥要注意,为什么是s[i].x - 1⽽不是s[i].x呢?原因很简单,举个例⼦,如果有三个区间1-3,7-8,3-4,那么最终选择的⼀定是1-3和7-8,因为区间之间不允许出现重复,如果选择1-3和3-4,那么3就是重复点,所以这⾥要⽤s[i].x - 1⽽不是s[i].x,另外,再计算total时要注意,在闭区间a,b中,中间元素的个数为a-b+1,⽽不是a-b代码:#include using namespace std;const int maxm = 2005;int dp[maxm];struct node{ int x; int y; int total;};bool cmp(node a , node b){ return a.y < b.y;}int main(){ int n; cin >> n; node s[n]; for(int i = 0 ; i < n ; i++) { cin >> s[i].x >> s[i].y; s[i].total = s[i].y - s[i].x + 1; //计算区间元素个数 } sort(s,s+n,cmp); for(int i = 0 ; i < n ; i++) { for(int j = s[n-1].y ; j >= s[i].y ; j--) dp[j] = max(dp[j],dp[s[i].x-1] + s[i].total); } cout << dp[s[n-1].y]; return 0;}

2023年8月1日发(作者:)

经典动态规划----饥饿的⽜(hunger)饥饿的⽜(hunger)Description⽜在饲料槽前排好了队。饲料槽依次⽤1到N(1<=N<=2000)编号。每天晚上,⼀头幸运的⽜根据约翰的规则,吃其中⼀些槽⾥的饲料。约翰提供B个区间的清单。⼀个区间是⼀对整数start-end,1<=start<=end<=N,表⽰⼀些连续的饲料槽,⽐如1-3,7-8,3-4等等。⽜可以任意选择区间,但是⽜选择的区间不能有重叠。当然,⽜希望⾃⼰能够吃得越多越好。给出⼀些区间,帮助这只⽜找⼀些区间,使它能吃到最多的东西。在上⾯的例⼦中,1-3和3-4是重叠的;聪明的⽜选择{1-3,7-8},这样可以吃到5个槽⾥的东西。Input第⼀⾏,整数B(1<=B<=1000)第2到B+1⾏,每⾏两个整数,表⽰⼀个区间,较⼩的端点在前⾯。Output仅⼀个整数,表⽰最多能吃到多少个槽⾥的⾷物。Sample Input 131 37 83 4Sample Output 15问题虽然看着⽐较复杂,但可以转换成⼀个简单的01背包问题,动态⽅程dp[j] = max(dp[j],dp[s[i].x - 1] + s[i].total)这⾥要注意,为什么是s[i].x - 1⽽不是s[i].x呢?原因很简单,举个例⼦,如果有三个区间1-3,7-8,3-4,那么最终选择的⼀定是1-3和7-8,因为区间之间不允许出现重复,如果选择1-3和3-4,那么3就是重复点,所以这⾥要⽤s[i].x - 1⽽不是s[i].x,另外,再计算total时要注意,在闭区间a,b中,中间元素的个数为a-b+1,⽽不是a-b代码:#include using namespace std;const int maxm = 2005;int dp[maxm];struct node{ int x; int y; int total;};bool cmp(node a , node b){ return a.y < b.y;}int main(){ int n; cin >> n; node s[n]; for(int i = 0 ; i < n ; i++) { cin >> s[i].x >> s[i].y; s[i].total = s[i].y - s[i].x + 1; //计算区间元素个数 } sort(s,s+n,cmp); for(int i = 0 ; i < n ; i++) { for(int j = s[n-1].y ; j >= s[i].y ; j--) dp[j] = max(dp[j],dp[s[i].x-1] + s[i].total); } cout << dp[s[n-1].y]; return 0;}