1 条题解

  • 0
    @ 2025-8-24 21:31:10

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar ysner
    这个家伙不懒,但也什么都没有留下

    搬运于2025-08-24 21:31:10,当前版本为作者最后更新于2018-02-08 08:44:04,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


    这题有点难想啊,看了一个小时才有思路,也许是我太弱了

    首先,这道题肯定是DP。

    其次,分析样例,会发现题目有个隐藏条件:只能用开局的V元钱买入药品。

    经过对题面的研究,我们可以发现,那一长串药物合成关系实在不好在DP中用上,我们应当把他们变得易于处理,如用ans[i][j]表示第i个物品在用j次魔法的前提下所需最小代价(即原材料价钱)。

    但ans[i][j]不太好直接求,我们可以再开一个DP数组ant[i][j]表示前i个药品在使用j次魔法前提下合成所需最小代价。这样就能通过ant[i][j]将合成原材料和合成品联系起来,顾及到 需要魔法总次数 等诸多因素。

    有了以上作为基础,DP处理出结果就方便多了。设DP[i][j]为使用第i次魔法,使用j块钱所获最大利润,依此列式即可。

    还有,一种药品可能有多种合成方式。我因把药品与合成关系一一对应WA了一版。

    #include<bits/stdc++.h>
    #define ll long long
    #define re register
    #define il inline
    #define fp(i,a,b) for(re int i=a;i<=b;i++)
    #define fq(i,a,b) for(re int i=a;i>=b;i--)
    using namespace std;
    const int N=300;
    int m,n,q,k,s[N],h[N],op,ans[N][N],dp[N][1005],ant[N][50];
    struct line
    {
      int a,l,p[N];
    }e[N];
    il int gi()
    {
      re int x=0,t=1;
      re char ch=getchar();
      while((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
      if(ch=='-') t=-1,ch=getchar();
      while(ch>='0'&&ch<='9') x=x*10+ch-48,ch=getchar();
      return x*t;
    }
    int main()
    {
      n=gi();m=gi();q=gi();k=gi();
      fp(i,1,n) s[i]=gi(),h[i]=gi();
      fp(i,1,m)
        {
          e[i].a=gi();e[i].l=gi();
          fp(j,1,e[i].l) e[i].p[j]=gi();
        }
      fp(i,1,n) fp(j,0,k) ans[i][j]=s[i];
      fp(o,1,k)
        fp(i,1,m)
          {
            fp(j,1,e[i].l)//枚举一合成关系中的物品
          {
            fp(t,0,o-1)//总魔法次数
              {
            ant[j][t]=1e9;
            fp(tt,0,t)//当前物品使用魔法次数 
            ant[j][t]=min(ant[j][t],ant[j-1][t-tt]+ans[e[i].p[j]][tt]);
              }
          }
        ans[e[i].a][o]=min(ans[e[i].a][o],ant[e[i].l][o-1]);
          }//处理药品合成信息
      fp(i,1,n)
        fp(j,0,k)
        fp(t,0,k-j)//枚举当前物品使用魔法次数
        fp(s,0,q-ans[i][j])//枚举使用钱数
        dp[j+t][s+ans[i][j]]=max(dp[j+t][s+ans[i][j]],dp[t][s]+h[i]-ans[i][j]);//简单DP求解
      printf("%d\n",dp[k][q]);
      return 0;
    }
    
    
    • 1

    信息

    ID
    829
    时间
    1000ms
    内存
    125MiB
    难度
    6
    标签
    递交数
    0
    已通过
    0
    上传者