最大工作量问题新的解法(不会证明)

原创 2015年07月08日 15:51:24

上次说到的那个问题,是用暴力破解,但是我电脑跑到30位的时候就跑不动了,现在我想出一种新的算法,经过验证是对的,但是我无法证明这种算法的正确性,请数学大神帮我证明无比感谢,我再重新描述一下问题:

         小明的导师给小明分配任务,每天都有不为0的任务量,如20,40,10,20,但是小明有心脏有问题,最多连续工作两天就必须休息一天,这让小明的导师很头疼,请问如果给定任务列表,小明怎么安排才能做最多的工作,求小明最多干多少活。

我的思路是这样的:每一天只有两种状态,一种是工作,一种是休息,我们就取到当天为止最大的工作量,所以要记录小明已经连续工作的天数,如果小明已经连续工作零天,那么当天必须工作才能获取的最大值,(我们把工作的顺序记录下来1表示工作,0表示休息,最终以便求和);如果小明已经工作一天那么,就让小明今天也工作才能达到最大值;如果说小明已经连续工作了两天,那我们先把今天休息,然后算出最大工作量然后记录下来,然后如果今天选择工作的话,那么就必须昨天休息,或者是前天休息,才能让今天继续工作,所以分别把昨天休息,和前天休息的最大工作量算出来,然后比较这三种工作量,取最大的工作量,然后把对应最大工作量的顺序记录下来。然后再进行下一天的决策。

        注意上面是我递推的思路,即(d代表工作天数,max代表当前最大工作量,work代表当天的工作量)

        if d<=1

        max=max+    work;

        else

        max=max{  3中决策的最大工作量 };


需要注意的是,每次要决策完后一定要把决策的工作序列记录下来,以便后面调用,如  1101等等,这个算法可以说是一种动态规划算法,也可以说是一种贪心算法,现在就是没有证明这种算法的正确性,请大神证明:我的实现如下(java)


public class Main3 {


static class Node{
boolean[] all=null;
int index=0;
int days=0;

public Node(int length){
all=new boolean[length];
}

public int sum(int[] workList){
int sum=0;
for(int i=0;i<index;i++){
if(all[i]){
  sum+=workList[i];
}
}
return sum;
}

public static Node max(Node a,Node b,int[] workList){
return a.sum(workList)>b.sum(workList)?a:b;
}

public static Node max(Node a,Node b,Node c,int[] workList){
Node temp=max(a,b,workList);
return max(temp,c,workList);
}

public void copy(Node node){
for(int i=0;i<index;i++){
node.all[i]=all[i];
node.index=index;
node.days=days;
}
}
}

public static int getMax(int[] workList){
if(workList.length<=2){
int sum=0;
for(Integer temp:workList){
sum+=temp;
}
return sum;
}else{
Node pre=new Node(workList.length);
pre.all[0]=true;
pre.all[1]=true;
pre.index=2;
pre.days=2;
Node now=null;
for(int i=2;i<workList.length;i++){

if(pre.days==2){
//这一天休息创建一个Node
Node a=new Node(workList.length);
pre.copy(a);
a.days=0;
a.all[a.index]=false;
a.index++;
//这一天上班,但是让昨天不上班
Node b=new Node(workList.length);
pre.copy(b);
   b.days=1;
   b.all[b.index]=true;
   b.all[b.index-1]=false;
   b.index++;
   //这一天上班,但是让前天天不上班
   Node c=new Node(workList.length);
   pre.copy(c);
   c.all[c.index]=true;
   c.all[c.index-2]=false;
c.index++;
//选取最大值
now=Node.max(a, b, c, workList);
}else{
//如果这已经工作天数不是2,那么今天工作肯定达到目前最大值
Node d=new Node(workList.length);
pre.copy(d);
d.days=pre.days+1;
d.all[d.index]=true;
d.index=pre.index+1;
now=d;
}
pre=now;
}
return now.sum(workList);
}
}

public static void main(String[] args) {
int[] workList=new int[]{2000,10,2000,2000};
System.out.println(getMax(workList));
}
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

最大工作量问题

关于最大工作量的问题,暴力解决

java 之连续子序列最大和问题的四个解法

import java.util.Random; public final class MaxSumTest {     static private int seqStart = 0;   ...

KT学算法(一)——数列连续子列最大和问题的O(n)解法

深刻意识到算法的重要性。从头开始,积累基本的算法模型。问题描述数列连续子列最大和问题是指:给定一个数列A,求出一个子数列,{Ai,Ai+1,Ai+2,……,Aj},其中i...

最大字段和的分治解法

  • 2011年06月10日 23:47
  • 982B
  • 下载

12 打印1到最大的N位数(递归和非递归解法)

打印1到最大的N位数(递归和非递归解法)

Dinic 二分图最大匹配最大流解法(来自lixiyi学姐的模板

模板

最大连续和的四种解法

最大连续和问题: 给出一个长度为n的序列A1,A2,A3,…An,求最大连续和。 即:找到1...

hdu 1864 最大报销额 01背包 解法

最大报销额 Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submi...

hdu 1231 最大连续子序列 yy+dp+数据结构解法

1:线段树解法 对于每一个i求出最大的(i-k)区间内的sum值及id #include #include #include #include #include #include #include ...

变形二叉树中节点的最大距离(树的最长路径)——非递归解法

问题描述: 如果我们把二叉树看成一个图,父子节点之间的连线看成是双向的,我们姑且定义"距离"为两节点之间边的个数。  写一个程序,求一棵二叉树中相距最远的两个节点之间的距离。测试用的树:    ...
  • hgqqtql
  • hgqqtql
  • 2014年10月04日 01:16
  • 1189
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:最大工作量问题新的解法(不会证明)
举报原因:
原因补充:

(最多只允许输入30个字)