Light OJ 1106 Gone Fishing (DP)

来源:互联网 发布:it培训公司排名 编辑:程序博客网 时间:2024/06/05 06:06

解析:由于路径的输出要求,这里使用逆推的方式更加合适。

设dp[i][j]为从i开始,剩余时间为j的最大捕鱼量。

枚举在第i个湖上钓鱼的时间k,则有dp[i][j] = max(dp[i+1][j-k]+k时间内能钓到的鱼的数量)


[code]:

#include<cstdio>#include<cstring>#include<algorithm>using namespace std;int n,m,f[30],d[30],t[30],dp[30][200],pr[30][200];int tim[30],top;void init(){    memset(dp,-1,sizeof(dp));    memset(pr,-1,sizeof(pr));    int num,j;    for(j=0;j<=m;j++){        num = d[n-1]?min(j,(f[n-1]-1)/d[n-1]+1):j;        dp[n-1][j] = num*(2*f[n-1]-(num-1)*d[n-1])/2;    }}int main(){    int i,j,k,cas;    scanf("%d",&cas);    for(int T=1;T<=cas;T++){        scanf("%d%d",&n,&m);        m *= 12;        for(i = 0;i < n;i++) scanf("%d",&f[i]);        for(i = 0;i < n;i++) scanf("%d",&d[i]);        for(i = 0;i < n-1;i++) scanf("%d",&t[i]);        init();        int num,tmp;        for(i = n-2;i >= 0;i--){            for(j = 0;j <= m;j++){                num = d[i]?min(j,(f[i]-1)/d[i]+1):j;                dp[i][j] = num*(2*f[i]-(num-1)*d[i])/2;                for(k = j;k >= t[i];k--){                    num = d[i]?min(k-t[i],(f[i]-1)/d[i]+1):(k-t[i]);                    tmp = dp[i+1][j-k]+num*(2*f[i]-(num-1)*d[i])/2;                    if(dp[i][j] < tmp){                        dp[i][j] = tmp;                        pr[i][j] = j-k;                    }                }            }        }        printf("Case %d:\n",T);        int t1,t2;        t1 = 0,t2 = m;top = 0;        while(t2 != -1){            tim[top++] = t2 - (pr[t1][t2]==-1?0:(pr[t1][t2]+t[t1]));            t2 = pr[t1][t2];            t1++;        }        for(;t1 < n;t1++) tim[top++] = 0;        for(i = 0;i < top;i++){            if(i) printf(", ");            printf("%d",tim[i]*5);        }        printf("\nNumber of fish expected: %d\n",dp[0][m]);    }    return 0;}


0 0