• (2022牛客多校四)A-Task Computing (排序+动态规划)


    题目:

    样例输入:

    1. 5 2
    2. 1 2 3 4 5
    3. 12000 11000 10000 9000 8000

     样例输出:

    8.5000000000000000

    题意:从n个任务中选m个(a1,a2,……,am)出来并任意排序,收益是

     求最大收益。

    看到公式的下标分布就知道这个值是跟任务的顺序有关的,所以我们应该先考虑按照什么样的顺序进行排序,一般常见的方法都是逐步调整法,就是说先假设一种顺序,然后交换其中两个相邻元素的位置,算出来两种排序方式对应的答案,进行比较就可以知道按照什么进行排序了!

    下面是调整的过程:

    我们先对n个任务按照上述方式进行排序,那么从里面任意选出来m个都是满足上述排序规则的,所以问题就转化为了我们如何从n个任务中选出来m个任务。

    我一开始想的是利用f[i][j]表示前i个任务中选出j个任务所能得到的最大值,再利用一个mul[i][j]表示达到f[i][j]状态时的乘积,然后递推方程就是:

    f[i][j]=max(f[i-1][j],f[i-1][j-1]+w[i]*mul[i-1][j-1]),再更新一下mul数组

    但是后来发现这样是存在问题的,原因就在于我们从前i个任务中选j个任务所能得到的最大值并不一定是从前i-1个任务中选j-1个任务或者选j个任务得到的最大值,因为对于从前i-1个任务中选取的任务数不同会直接影响所选取任务的乘积,那么这个是会对答案造成很大影响的,所以不能这么做。

    正解:

    之所以我们刚才考虑的那种动态转移方程不行就是因为后面的值取决于前面的两个值,一个是乘积另一个是和式,所以我们无法直接根据和式的值来向后转移,但是通过上面的公式变形后我们可以清楚的发现,我们可以从后往前推导,这样前面值只跟后面的和式有关,而不再与乘积有关,这样我们就可以进行动态转移了,只是更新方式会略有变化,这种方法还是挺妙的。

    设f[i][j]表示考虑第i~n个任务选出来j个任务的最大值,然后我们直接倒序更新该数组

    动态转移方程:f[i][j]=max(f[i+1][j],f[i+1][j-1]*p[i].q+p[i].w)

    下面是代码:

    1. #include
    2. #include
    3. #include
    4. #include
    5. #include
    6. #include
    7. #include
    8. #include
    9. using namespace std;
    10. typedef long long ll;
    11. const int N=1e5+10;
    12. struct node{
    13. ll w;
    14. double q;
    15. }p[N];
    16. double f[N][30];//f[i][j]表示考虑第i~n个任务选出来m个任务的最大值
    17. bool cmp(node a,node b)
    18. {
    19. return (a.w-b.q*a.w+a.q*b.w-b.w)>=0;
    20. }
    21. int main()
    22. {
    23. int n,m;
    24. cin>>n>>m;
    25. for(int i=1;i<=n;i++)
    26. scanf("%lld",&p[i].w);
    27. for(int i=1;i<=n;i++)
    28. {
    29. scanf("%lf",&p[i].q);
    30. p[i].q/=10000;
    31. }
    32. sort(p+1,p+n+1,cmp);
    33. for(int i=n;i>=1;i--)
    34. for(int j=1;j<=m;j++)
    35. f[i][j]=max(f[i+1][j],f[i+1][j-1]*p[i].q+p[i].w);
    36. printf("%.8lf",f[1][m]);
    37. return 0;
    38. }

  • 相关阅读:
    基于微信小程序新生报到系统(微信小程序毕业设计)
    數據集成平台:datax將MySQL數據以query方式同步到hive
    kubernetes 起几个节点,就会有几个flannel pod
    K8S原理架构与实战教程
    百度笔记能优化吗
    公众号开发实践:用PHP实现通过接口自定义微信公众号菜单
    基于STM32+射频模块设计的导盲杖
    看一下链表结构
    快速搭建 SpringCloud Alibaba Nacos 配置中心
    c++的引用和指针
  • 原文地址:https://blog.csdn.net/AC__dream/article/details/126084563