上图表达的是一个人在工厂上班的任务计划,横坐标代表时间,灰色区域的黑色数字代表任务的编号,红色数字代表完成任务所得到的报酬,并且这个人在同一时间内只能完成一个任务,求这个在这一天工作中所获得的最大报酬。
下面是由题意列出的递归方程:
opt(i)=v(i)+opt(prev(i)) 选择当前的任务
opt(i) = opt(i-1) 不选择当前的任务
上面方程中的opt(i)代表考虑到任务i时所获得的最大报酬,v(i)代表当前任务i所对应的报酬,prev(i)代表当前任务i前面还可以做哪个任务。由图得到了v(i)和prev(i)所对应的数组int[] prev = new int[] {0,0,0,1,0,2,3,5};和
int[] v = new int[] {5,1,8,4,6,3,2,4};所以最后得到了这个递归方程所对应的java代码:
public class ChoiceOrNot {
//存储在选择第i个任务时,它前面可以做的任务编号,0表示无任务可做
static int[] prev = new int[] {0,0,0,1,0,2,3,5};
//存储每个任务所对应的价值
static int[] v = new int[] {5,1,8,4,6,3,2,4};
//比较两个整数的大小,并返回较大的整数
public static int max(int a,int b) {
if(a>=b)
return a;
else
return b;
}
//求做任务可以得到的最大价值(递归法)
public static int rec_opt(int i) {
if(i<=0)
return 0;
if(i==1)
return v[i-1];
int choice = v[i-1] + rec_opt(prev[i-1]);
int notChoice = rec_opt(i-1);
return max(notChoice,choice);
}
//求做任务可以得到的最大价值(动态规划法)
public static int dp_opt() {
int[] opt = new int[v.length+1];
opt[0] = 0;
opt[1] = v[0];
for(int i=1;i<opt.length;i++) {
int choice = v[i-1]+opt[prev[i-1]];
int notChoice = opt[i-1];
opt[i] = max(choice,notChoice);
}
return opt[opt.length-1];
}
public static void main(String[] args) {
int result1 = rec_opt(8);
int result2 = dp_opt();
System.out.println(result1);
System.out.println(result2);
}
}
运行结果为: