当前位置: 首页 > 图灵资讯 > 技术篇> poj-1042

poj-1042

来源:图灵教育
时间:2023-05-24 09:27:32

#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】 代表从第一个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, 那么最大的鱼数就是这段时间在第一个lake能钓到的鱼.

事实上,三维数组更方便

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

这个题目也可以用贪心法, 以后补上.

为便于跟踪轨迹, 除记录每种情况的最大鱼数外, 还记录了停留时间.

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

上一篇:

poj-1080

下一篇:

支付链接转码util