当前位置:   article > 正文

蓝桥杯2022年第十三届决赛真题-搬砖

蓝桥杯2022年第十三届决赛真题-搬砖

 输入:

  1. 5
  2. 4 4
  3. 1 1
  4. 5 2
  5. 5 5
  6. 4 3

输出:

10

解题思路:这个题一看很容易就会想到01背包DP,dp[i][j]表示从前i个物品中选,总重量为j的最大价值是多少,具体转移方程如下:

首先对于所有的j初始化:dp[i][j]=dp[i-1][j]

当前物品的重量w,价值v满足,v>=j时,dp[i][j+w]=max(dp[i][j+w],dp[i-1][j]+v)

然后就是排序问题,这是本题最主要的难点了(个人认为)。如果有两个物品i和j,i能放在j的上面,j却不能放在i的上面,此时这样的排列顺序是最优的,其应该满足如下关系式:

wi+sum<=vj

wj+sum>vi(sum为除了物品i,j之外的所有物品的重量和)

可得:wi<=vj,vi<wj

于是可以得到排序条件是wi+vi<wj+vj

上代码:

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. const int N=1010;
  4. struct node{
  5. int v;
  6. int w;
  7. }p[N];
  8. int n,dp[N][N*20];
  9. bool cmp(node a,node b)
  10. {
  11. return a.w+a.v<b.w+b.v;
  12. }
  13. int main()
  14. {
  15. cin>>n;
  16. for(int i=1;i<=n;i++)
  17. scanf("%d%d",&p[i].w,&p[i].v);
  18. sort(p+1,p+1+n,cmp);
  19. for(int i=1;i<=n;i++)
  20. {
  21. for(int j=0;j<=n*20;j++)
  22. dp[i][j]=dp[i-1][j];
  23. for(int j=p[i].v;j>=0;j--)
  24. dp[i][j+p[i].w]=max(dp[i][j+p[i].w],dp[i-1][j]+p[i].v);
  25. }
  26. int ans=-1;
  27. for(int i=n*20;i>=0;i--)
  28. ans=max(ans,dp[n][i]);
  29. cout<<ans<<endl;
  30. return 0;
  31. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/586229
推荐阅读
相关标签
  

闽ICP备14008679号