poj-1042

#include <stdio.h>
#include <malloc.h>


struct fishingOP {
    int maxFishing;
    int stayInterval;
};

typedef struct fishingOP fishingOP;

void getMostFish(int * fi, int * di, int * ti, int lakeNum, int intervalNum) {
    fishingOP ** matrix = (fishingOP **)malloc(sizeof(fishingOP *) * lakeNum);
    for (int i = 0; i < lakeNum; i++) {
        *(matrix + i) = (fishingOP *)malloc(sizeof(fishingOP) * (intervalNum + 1));
    }
    for (int i = 0; i < lakeNum; i++) {
        for (int j = 0; j < intervalNum + 1; j++) {
            matrix[i][j].maxFishing = -1;
        }
    }


    for (int i = lakeNum-1; i >= 0; i--) {
        for (int j = 0; j < intervalNum + 1; j++) {
            if (j == 0) { // no time to fishing
                // printf("%d %d 0\n", i, j);
                matrix[i][j].maxFishing = 0;
                matrix[i][j].stayInterval = 0;
                continue;    
            } else if (i == lakeNum-1 && j == 1) { // can only fishing from the last lake, and only 1 interval
                matrix[i][j].maxFishing = fi[i];
                // printf("%d %d %d\n", i, j, matrix[i][j].maxFishing);
                matrix[i][j].stayInterval = 1;
                continue;
            } else if (i == lakeNum-1 && j >= 1) { // can only fishing from the last lake, stay more than 1 interval
                if (fi[i] - di[i] *(j - 1) > 0) {
                    matrix[i][j].maxFishing = matrix[i][j-1].maxFishing + fi[i] - di[i] *(j-1);
                } else {
                    matrix[i][j].maxFishing = matrix[i][j-1].maxFishing; // if have stay, but no fish, of course equals previuos interval
                }
                matrix[i][j].stayInterval = j;
                // printf("%d %d %d\n", i, j, matrix[i][j].maxFishing);
                continue;
            } else {
                int stayInterval = 0;

                if (j - ti[i] < 0) { // no time to next lake
                    int fishNumCurLakeAcc = 0;
                    int fishIntervalNum = fi[i];
                    for (int k = 1; k <= j; k++) { // iterate all possible stay interval num
                        fishNumCurLakeAcc += fishIntervalNum;
                        fishIntervalNum -= di[i];
                        if (fishIntervalNum < 0) {
                            fishIntervalNum = 0;
                        }
                    }
                    matrix[i][j].maxFishing = fishNumCurLakeAcc;
                    stayInterval = j;
                    matrix[i][j].stayInterval = stayInterval;
                    
                } else { // still have time to go next lake, so can fish some time here.
                    int maxfishingNum = matrix[i+1][j - ti[i]].maxFishing; // no fishing in lake i.
                    int fishNumCurLakeAcc = 0;
                    int fishIntervalNum = fi[i];
                    
                    for (int k = 1; k <= j; k++) { // iterate all possible stay interval num
                        fishNumCurLakeAcc += fishIntervalNum;
                        int curFishNum;
                        if (j - k - ti[i] >= 0) {
                            curFishNum = fishNumCurLakeAcc + matrix[i+1][j - k - ti[i]].maxFishing;
                        } else {
                            curFishNum = fishNumCurLakeAcc;
                        }
                        fishIntervalNum -= di[i];
                        if (fishIntervalNum < 0) {
                            fishIntervalNum = 0;
                        }
                        if (curFishNum >= maxfishingNum) {
                            maxfishingNum = curFishNum;
                            stayInterval = k;
                        }
                    }
                    matrix[i][j].maxFishing = maxfishingNum;
                    matrix[i][j].stayInterval = stayInterval;
                }
                
                // printf("%d %d %d stay: %d\n", i, j, matrix[i][j].maxFishing, matrix[i][j].stayInterval*5);
            }
        }
    }

    int i = 0;
    int j = intervalNum;
    bool firstTime = 1;
    while(1) {
        if (i == lakeNum) {
            break;
        }
        if (!firstTime) {
            printf(", ");
        } else {
            firstTime = 0;
        }
        int stayInterval;
        if (j >= 0) {
             stayInterval = matrix[i][j].stayInterval;
        } else {
            stayInterval = 0;
        }
        printf("%d", stayInterval*5);
        j = j - stayInterval - ti[i];
        i = i + 1;
    }

    printf("\n");

    printf("Number of fish expected: %d\n\n", matrix[0][intervalNum].maxFishing);

    for (int i = 0; i < lakeNum; i++) {
        free(*(matrix + i));
        *(matrix + i) = NULL;
    }
    free(matrix);
    matrix = NULL;

}


int main() {
    while(1) {
        int lakeNum = 0;
        int hour = 0;
        scanf("%d", &lakeNum);
        if (lakeNum == 0) {
            break;
        }
        scanf("%d", &hour);
        int intervalNum = hour*12;
        int * fi = (int *)malloc(sizeof(int) * lakeNum);
        int * di = (int *)malloc(sizeof(int) * lakeNum);
        for (int i = 0; i < lakeNum; i++) {
            scanf("%d", fi+i);
        }
        for (int i = 0; i < lakeNum; i++) {
            scanf("%d", di+i);
        }
        int * ti = (int *)malloc(sizeof(int) * (lakeNum-1));
        for (int i = 0; i < lakeNum-1; i++) {
            scanf("%d", ti + i);
        }

        getMostFish(fi, di, ti, lakeNum, intervalNum);

        free(fi);
        fi = NULL;
        free(di);
        di = NULL;
        free(ti);
        ti = NULL;
    }

}


DP, 变种背包, 只不过是每件物品有多个数量的背包, 并且还要注意lake在全部钓完鱼以后,继续掉就不能再减di。

上面用了二维数组

matix【i】【j】 代表的是从第i个lake开始, 总共有j个interval(5分钟)情况下的 能钓到的最多鱼。

考虑的情况有:

<1> j == 0, 没有时间钓鱼了, 那么最大鱼数为0

<2> i == lakeNum, 从最后一个lake开始钓, 那最大鱼数就是从此lake能钓到的所有鱼。

<3> j 不足以 跑到下一个lake, 那么就只能在lake钓, 最大鱼数就是在j的时间内能钓的最多鱼

<4> j还可以跑到下一个lake, 那么就可以再分了, 在此lake停留一些时间(1 ~ j),

      比较每种停留时间下能钓到的最大鱼数。(多个选择, 和0-1背包的区别, 0-1背包每个物品只有一件)

     注意这里也用两种情况:

    (1) 停留了K, 剩下的时间还能跑到下一个lake, 那么鱼数 就是 这k段时间里钓到的鱼 加上  matix[i+1][j -k - 到下一个lake花的时间]

    (2)停留K, 但是剩下时间不够到下一个lake, 那么最大鱼数就是这j段时间在第i个lake能钓到的鱼.


其实一个三维的数组更方便

matix[i][j][k]  代表 从第i个lake开始, 总共由 j 个interval, 并且在 第i个lake 钓 k 段时间的最大鱼数.

本题还可以用贪心法, 以后补上.


为了方便追踪轨迹, 除了记录每个情况的最大鱼数, 还记录了停留的时间.

DP在实际编写的时候, 难在步骤之间耦合紧, 考虑的极限情况也比较多.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值