codevs科技庄园

/*
    因为每一秒只能走一个单位长度,而每走一个单位长度又会消耗一个体力值,如果体力值没有了时间还有也只能按照体力值计算,反之一样,所以V对于时间和体力值取小
cnt记录有桃子的树的个数,node[cnt].c表示在第cnt颗树上每次可摘桃子的个数,node[cnt].v表示从起点到第cnt棵树来回的距离,wz[i][j]表示从(0,0)到(i,j)范围内树的个数
node[i]记录第i棵树可以摘的次数     dp方程式为ans[j]=max(ans[j],ans[j-k*node[i].v]+k*node[i].c),不摘第j棵树的第k次与摘了之后获得的桃子取大 
*/
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define maxn 1010
struct node{
    int v,c,k;
}N[maxn*maxn];
int V;
int ans[maxn]={0},wz[maxn][maxn];
int cnt=0,n,m,t,a;
int main()
{
    scanf("%d%d%d%d",&n,&m,&t,&a);
    if(t<a-1) V=t;//因为最后要有剩余体力所以此处先减1 
    else V=a-1;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
        {
            int u;
            scanf("%d",&u);
            if(u)
            {
                N[++cnt].c=u;
                N[cnt].v=2*(i+j);
                wz[i][j]=cnt;
            }
        }
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
        {
            int u;
            scanf("%d",&u);
            if(u)
                N[wz[i][j]].k=u;
        }
    for(int i=1;i<=cnt;i++)
        for(int j=V;j>=1;j--)
            for(int k=1;k<=N[i].k;k++)
                if(j-k*N[i].v>=0)
                    ans[j]=max(ans[j],ans[j-k*N[i].v]+k*N[i].c);
    printf("%d",ans[V]);
    return 0;
}
原文地址:https://www.cnblogs.com/xiaoningmeng/p/5777794.html