动态编程,选择最高总值

时间:2016-02-10 01:34:49

标签: dynamic-programming

数据: 按顺序增加的整数列表(0,1,2,3,4,5 .......) 属于这些整数的值列表。例如,0 = 33,1 = 45,2 = 21,......等。

增量变量x,表示最小跳跃值。

x是每次跳跃的值。例如,如果x = 2,如果选择1,则不能选择2.

我需要确定选择整数的最佳方法,给定一些(x),从值列表中产生最高的总值。

实施例

A = a set of 1 foot intervals (0,1,2,3,4,5,6,7,8,9)
B = the amount of money at each interval (9,5,7,3,2,7,8,10,21,12)
Distance = the minimum distance you can cover
- i.e. if the minimum distance is 3, you must skip 2 feet and leave the money, then you can
pick up the amount at the 3rd interval. 

if you pick up at 0, the next one you can pick up is 3, if you choose 3 you can 
next pick up 6 (after skipping 4 and 5). BUT, you dont have to pick up 6, you 
could pick up 7 if it is worth more. You just can't pick up early. 

So, how can I programmatically make the best jumps and end with the most money at the end? 

1 个答案:

答案 0 :(得分:1)

所以我使用下面的等式来计算动态编程中的opt值:

这里d是距离。

if (i -d) >= 0
opt(i) = max (opt(i-1), B[i] + OPT(i-d));

else 

opt(i) = max (opt(i-1), B[i]);

用于计算OPT值的Psuedo代码:

int A[] = {integers list}; // This is redundant if the integers are consecutive and are always from 0..n.
int B[] = {values list};
int i = 0;
int d = distance; // minimum distance between two picks.
int numIntegers = sizeof(A)/sizeof(int);

int opt[numIntegers];

opt[0] = B[0]; // For the first one Optimal value is picking itself.
for (i=1; i < numIntegers; i++) {

    if ((i-d) < 0) {
        opt[i] = max (opt[i-1], B[i]);
    } else {
        opt[i] = max (opt[i-1], B[i] + opt[i-d]);
    }

}

根据OP关于从B获取所选整数的要求进行编辑:

for (i=numIntegres - 1; i >= 0;) {
    if ((i == 0) && (opt[i] > 0)) {
        printf ("%d ", i);
        break;
    }
    if (opt[i] > opt[i-1]) {
        printf ("%d ", i);
        i = i -d;
    } else {
        i = i - 1;
    }

}

如果A []没有从0到n的连续整数。

int A[] = {integers list}; // Here the integers may not be consecutive
int B[] = {values list};
int i = 0, j = 0;
int d = distance; // minimum distance between two picks.
int numAs = sizeof(A)/sizeof(int);
int numIntegers = A[numAs-1]

int opt[numIntegers];

opt[0] = 0;
if (A[0] == 0) {
    opt[0] = B[0]; // For the first one Optimal value is picking itself.
    j = 1;
}

for (i=1; i < numIntegers && j < numAs; i++, j++) {
    if (i < A[j]) {
        while (i < A[j]) {
            opt[i] = opt[i -1];
            i = i + 1:
        }
    }

    if ((i-d) < 0) {
        opt[i] = max (opt[i-1], B[j]);
    } else {
        opt[i] = max (opt[i-1], B[j] + opt[i-d]);
    }

}