Greedy Tino动态规划问题-搬橘子

  • 例7.6 Greedy Tino(九度教程第100题)

题目大意:给定n个橘子的重量,要求从这些橘子中选出若干个分成两堆,使得这两堆的重量相同,问这两堆橘子的总重量是多少?

解法:使用动态规划。dp[i][j]表示放入第i个橙子之后,第一堆比第二堆重j,两堆的总重量,dp[][]的每一个值代表一个状态,求出所有状态之后,dp[n][0]/2即为所得。
代码如下:

//动态规划问题
#include<bits/stdc++.h>
using namespace std;
#define INF 0x7fffffff
#define OFFSET 2000//因为两堆的重量差j可能是负数,所以选j+OFFSET作为数组下标
int ganju[101];//柑橘重量
int dp[101][4001];//状态转移数组,其中dp[i][j]表示放入第i个橙子之后,第一堆比第二堆重j,两堆的总重量
int main()
{
    int T;
    int cases=0;
    cin>>T;
    while(T--){
        int n;//n个柑橘
        cin>>n;
        int cnt=0;//记录有多少个重量非0的柑橘
        bool havezero=false;
        for(int i=1;i<=n;i++)
            {
                cin>>ganju[++cnt];//输入橘子的重量
                if(ganju[cnt]==0)
                {
                    cnt--;
                    havezero=true;
                }
            }
        n=cnt;
        //初始化
        for(int i=-2000;i<=2000;i++)
            dp[0][i+OFFSET]=-INF;//状态不存在
        dp[0][0+OFFSET]=0;//选0个橘子,两堆重量差是0时,重量和也是0
        //算法
        for(int i=1;i<=n;i++){//每一个橘子
            for(int j=-2000;j<=2000;j++){//每种重量
                int tmp1=-INF,tmp2=-INF;
                if(j+ganju[i]<=2000 && dp[i-1][j+ganju[i]+OFFSET]!=-INF)
                    tmp1=dp[i-1][j+ganju[i]+OFFSET]+ganju[i];//有第一堆转化而来
                if(j-ganju[i]>=-2000 && dp[i-1][j-ganju[i]+OFFSET]!=INF)
                    tmp2=dp[i-1][j-ganju[i]+OFFSET]+ganju[i];//由第二堆转化而来
                if(tmp1<tmp2)
                    tmp1=tmp2;5
                if(tmp1<dp[i-1][j+OFFSET])
                    tmp1=dp[i-1][j+OFFSET];//与柑橘不放入任何堆的原状态比较,取最大值
                dp[i][j+OFFSET]=tmp1;//加入这个橘子后,当前状态值为三个状态转化而来的最大值
            }
        }
        cases++;
        cout<<"Case"<<cases<<":";
        if(dp[n][0+OFFSET]==0)
            puts(havezero==true?"0":"-1");//puts()自动换行
        else
            cout<<dp[n][0+OFFSET]/2<<endl;

    }
    return 0;
}
全部评论

相关推荐

昨天 10:44
已编辑
南京大学 Java
实习的组没hc,令我愤恨的是拖了三周才挂我转正,导致期间也没法投递秋招流程不过好在运气不错,前脚投后脚就被一志愿约面了,一问发现是实习所在业务的下游(难绷)9.18&nbsp;一面&nbsp;1h20min1.&nbsp;自我介绍2.&nbsp;先做题:删除链表中的重复节点II3.&nbsp;聊美团实习。性能优化细节,以及如何实现算子的元信息记录逻辑不侵入业务代码等4.&nbsp;hashmap引入红黑树的目的5.&nbsp;既然红黑树效率比链表高,为何不一开始就用红黑树6.&nbsp;用二叉排序树或AVL可以吗7.&nbsp;线程池核心参数8.&nbsp;假如一段代码是用了大量的synchronized,效率很差,你会如何优化它?9.&nbsp;synchronized和基于AQS的锁有哪些区别10.&nbsp;那你觉得二者的性能有差别吗11.&nbsp;如果我们的一个线上系统出现了频繁的fullgc,如何排查并解决问题12.&nbsp;cms和g1,这两个你觉得分别适合什么场景13.&nbsp;对zgc有了解吗14.&nbsp;如何理解最左前缀原则15.&nbsp;一个表上a&nbsp;b&nbsp;c三个字段建了联合索引,现在的查询条件是a>1&nbsp;and&nbsp;c=1,问索引的使用情况?16.&nbsp;线上出现了慢查询,要怎么去定位和排查反问:1.&nbsp;部门业务(tsp)2.&nbsp;多久出结果9.22&nbsp;二面&nbsp;1h30min1.&nbsp;自我介绍2.&nbsp;挑一段实习讲一下3.&nbsp;实习难点4.&nbsp;其它有挑战的部分5.&nbsp;美团实习,你的ld是谁?(😨)6.&nbsp;实习内容细节,追问的比较狠。尤其是讲到考虑到压测机器被用来跑自动化测试的时候,diff流量和压测流量冲突的问题。面试官不断追问二者冲突会带来什么影响和为什么会影响,以及为何线上流量能与二者正常区分。这里把我问住了7.&nbsp;现场出题:int&nbsp;a&nbsp;=&nbsp;3Integer&nbsp;b&nbsp;=&nbsp;nullint&nbsp;c&nbsp;=&nbsp;a&nbsp;+&nbsp;blong&nbsp;d&nbsp;=&nbsp;1l&nbsp;+0x7fffffffint&nbsp;e&nbsp;=&nbsp;a&nbsp;+&nbsp;d运行以上代码,会发生什么?怎么解决?8.&nbsp;现场出题:Integer&nbsp;a&nbsp;=&nbsp;567Integer&nbsp;b&nbsp;=&nbsp;567sout(a&nbsp;==&nbsp;b)会输出什么?如何修改使结果符合预期?9.&nbsp;讲讲你所了解的并发编程10.&nbsp;你刚才提到了🔒,java中的🔒都用哪些,区别是啥,简单介绍下11.&nbsp;线程池简单讲讲12.&nbsp;电脑按下开机按钮,开机后打开面邀链接进行面试,这个过程计算机底层发生了哪些事情(408究极大杂烩,从硬件加电自检讲到引导扇区再到os进线程启动再到显卡协同液晶单元显示画面,再到打开链接的上层http交互到底层网卡的编码调制。整个一个大串烧)13.&nbsp;你刚才提到视频会议底层用udp,那为什么不用tcp14.&nbsp;mysql简单讲解下你所了解的(准备讲架构,被面试官拒绝了,说不用讲这么底层,说说偏应用层面的😂)15.&nbsp;怎么知道一个sql语句有没有走索引16.&nbsp;explain一般关注哪些字段17.&nbsp;过往的实习或项目中,印象最深刻的一张表,描述出来字段、索引情况18.&nbsp;根据刚才描述的表,即兴出了两道sql题19.&nbsp;你所写的sql语句中出现了select&nbsp;from&nbsp;where&nbsp;groupby&nbsp;having这些关键字,它们的执行顺序是怎样的20.&nbsp;算法题:二维矩阵行有序、列有序,查找某个值反问:1.&nbsp;部门技术栈2.&nbsp;面试流程(2技术)9.30&nbsp;意向
发面经攒人品
点赞 评论 收藏
分享
评论
1
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务