
I used DP instead of Greedy. But got WA on PoJ, though it passed all web-searched cases. Maybe I have to use Greedy.
BTW: a careless modification introduced an error, and it took me 1+ hours to debug. DETAILS
Sth. about this DP solution: dp[iLake][nCurrTotalTime + currentLakeTime] = dp[iLake - 1][nCurrTotalTime] + getFish(iLake, nCurrTotalTime, currentLakeTime);
Anyway, this is the first 2D DP problem I worked out :)
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <vector>
using namespace std; #define Max(a, b) (a) > (b) ? (a) : (b)
#define MAX_LAKE 25
#define MAX_TIME (16*12) // We are at lake i now, with total time of tTtlLake spent on previous lakes,
// and we'd like to spend myt time on lake i -> how many fishes we can get from lake i?
int getFish(int i, int tTtlLake, int myt, int *accti, int *fi, int *di)
{
if (myt == ) return ; // If any left, get fishes by time myt
int ret = , left = fi[i];;
while (left > && myt > )
{
ret += left;
left -= di[i];
myt--;
}
return ret;
} void backtrack(int path[MAX_LAKE + ][MAX_TIME], int si, int sk, int n, int h)
{
bool bHasSolution = false;
int opath[MAX_LAKE + ] = { };
int actTtl = ;
while (si > && path[si][sk] != -)
{
opath[si] = path[si][sk];
actTtl += opath[si];
sk -= path[si][sk];
si--;
bHasSolution = true;
}
// Actual results less than h?
if (actTtl < h)
{
bool allAfterZero = true;
for (int i = ; i <= n; i++)
{
if (opath[i] != )
{
allAfterZero = false;
}
}
if (allAfterZero)
{
opath[] += h - actTtl;
}
}
if (!bHasSolution)
{
opath[] = h;
}
for (int i = ; i <= n; i++)
{
printf("%d", opath[i] * );
if (i < n) printf(", ");
}
printf("\n");
} void calc(int n, int h, int *fi, int *di, int *ti, int *accti)
{
// Reset
int dp[MAX_LAKE + ][MAX_TIME];
int path[MAX_LAKE + ][MAX_TIME];
memset( dp, , sizeof(int) * MAX_TIME * (MAX_LAKE + ));
memset(path, -, sizeof(int)* MAX_TIME * (MAX_LAKE + )); // dp[currentLakeIndex, currentTtlTimeOnLake] = currTtlFishCnt. Note: no time on the way included
// dp[i + 1, tTtl + t] = dp[i, tTtl] + f(fi(i + 1), t) int maxFish = , maxI, maxT;
for (int i = ; i <= n; i++)
{
// time on the way so far
int tWay = accti[i-]; for (int t = h; t >=; t--) // descending is necessary: it required more miniutes to spend as earlier as possible
{
if (i == && t > ) continue; int leftTime = h - t - tWay;
leftTime = leftTime < ? : leftTime; for (int k = ; k <= leftTime; k++) // k is how much time left in total
{
int newV = dp[i - ][t] + getFish(i, t, k, ti, fi, di);
if (newV > dp[i][t + k])
{
dp[i][t + k] = newV;
path[i][t + k] = k;
//printf("-putting %d to [%d][%d]\n", k, i, t + k); if (newV > maxFish)
{
maxFish = newV;
maxI = i; maxT = t + k;
}
}
}
}
} backtrack(path, maxI, maxT, n, h);
printf("Number of fish expected: %d\n\n", maxFish);
} int main()
{
int n, h;
while (scanf("%d", &n), (n != ))
{
scanf("%d", &h); // all in 5min-interval
h *= ; int fi[MAX_LAKE + ] = { }; // initial fish cnt
int di[MAX_LAKE + ] = { }; // decrease rate
int ti[MAX_LAKE] = { }; // travel time
int accti[MAX_LAKE] = { }; // travel time // Get Input
for (int i = ; i <= n; i ++) scanf("%d", fi + i);
for (int i = ; i <= n; i ++) scanf("%d", di + i);
for (int i = ; i <= n - ; i++)
{
scanf("%d", ti + i);
accti[i] = ti[i] + accti[i - ];
} calc(n, h, fi, di, ti, accti);
} return ;
}