首页 > Web开发 > 详细

【BZOJ1017】[JSOI2008]魔兽地图(动态规划)

时间:2018-09-28 17:09:32      阅读:172      评论:0      收藏:0      [点我收藏+]

【BZOJ1017】[JSOI2008]魔兽地图(动态规划)

题面

BZOJ
洛谷

题解

状态设一下,\(f[i][j][k]\)表示第\(i\)个物品,有\(j\)个用于合成,总花费为\(j\)的最大力量,转移什么的,乱死了,复杂度感觉好假。

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
using namespace std;
#define ll long long
#define MAX 110
inline int read()
{
    int x=0;bool t=false;char ch=getchar();
    while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
    if(ch=='-')t=true,ch=getchar();
    while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
    return t?-x:x;
}
char ch[5];
int f[55][MAX][2010],g[2010];
int n,m,a[MAX],cost[MAX],lim[MAX];
struct Line{int v,next,w;}e[MAX];
int h[MAX],cnt=1,dg[MAX],ans[2010];
inline void Add(int u,int v,int w){e[cnt]=(Line){v,h[u],w};h[u]=cnt++;dg[v]++;}
void dfs(int u)
{
    if(!h[u])
    {
        lim[u]=min(lim[u],m/cost[u]);
        for(int i=0;i<=lim[u];++i)
            for(int j=0;j<=i;++j)
                f[u][j][i*cost[u]]=(i-j)*a[u];
        return;
    }
    for(int i=h[u];i;i=e[i].next)
    {
        dfs(e[i].v);
        cost[u]+=cost[e[i].v]*e[i].w;
        lim[u]=min(lim[u],lim[e[i].v]/e[i].w);
    }
    lim[u]=min(lim[u],m/cost[u]);
    for(int i=0;i<=lim[u];++i)
    {
        memset(g,-63,sizeof(g));g[0]=0;
        for(int j=h[u];j;j=e[j].next)
        {
            int v=e[j].v,w=e[j].w;
            for(int k=m;~k;--k)
            {
                int t=-1e9;
                for(int l=0;l<=k;++l)t=max(t,g[l]+f[v][i*w][k-l]);
                g[k]=t;
            }
        }
        for(int j=0;j<=i;++j)
            for(int k=0;k<=m;++k)
                f[u][j][k]=max(f[u][j][k],g[k]+a[u]*(i-j));
    }
}
int main()
{
    n=read();m=read();
    for(int i=1;i<=n;++i)
    {
        a[i]=read();scanf("%s",ch);
        if(ch[0]=='B')cost[i]=read(),lim[i]=read();
        else
        {
            int C=read();lim[i]=1e9;
            while(C--){int x=read(),w=read();Add(i,x,w);}
        }
    }
    memset(f,-63,sizeof(f));
    for(int i=1;i<=n;++i)
        if(!dg[i])
        {
            dfs(i);
            for(int j=m;~j;--j)
                for(int k=0;k<=j;++k)
                    ans[j]=max(ans[j],ans[j-k]+f[i][0][k]);
        }
    printf("%d\n",ans[m]);return 0;
}

【BZOJ1017】[JSOI2008]魔兽地图(动态规划)

原文:https://www.cnblogs.com/cjyyb/p/9719654.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!