• 救命(洛谷 U4525)


    题目背景

    XS中学的校长积劳成疾,最终由于无聊而卧病在沙发。需要药(pi)水(gu)拯救他的生活。

    题目描述

    现在有n种药水,编号分别为1..n,能拯救校长的药水编号为n

    每个药水都可以购买到,但有的价格很便宜,有的很贵。

    你还知道m种神奇的合成方法,可以将某些不同的药水合成成为一个新的药水。

    现在,你需要求出合成出n号药水所需要花费的最小金钱,以及在保证花费最小情况下的最少需要合成的次数。

    输入输出格式

    输入格式:

    第一行两个数n,m

    接下来n行,每行有一个数a[i],表示i号药水的价格。

    接下来m行,每行描述一个合成方法。

    对于每个合成方法:第一个数x表示所需要的药水的个数。接下来x个数,分别表示所需要的每个药水的编号,最后一个数表示这x个药水所合成的药水的编号

    输出格式:

    仅两个数,分别表示最小花费和满足该花费的最小合成次数,中间用空格隔开。

    输入输出样例

    输入样例#1:
    10 4
    1
    2
    3
    100
    4
    2
    2
    2
    100
    100
    3 1 2 3 4
    2 4 5 10
    2 6 7 9
    2 9 8 4
    
    输出样例#1:
    10 2

    说明

    n<=1000

    m<=10000

    2<=x<=10

    Tips:看标签!!!

    /*
      对于每种药,统计一个mon代表最小花费,step代表在mon基础上的最小步数,  不断用能合成i这种药的Σmon[j] 来更新mon[i],共更新n次就可以,最后求  mon[n]。
    */
    #include<cstdio>
    #include<iostream>
    #define N 1010
    #define M 10010
    using namespace std;
    int mon[N],step[N],n,m;
    struct node
    {
        int tot,s[11],t;
    };node a[M];
    int read()
    {
        char c=getchar();int num=0,flag=1;
        while(c<'0'||c>'9'){if(c=='-')flag=-1;c=getchar();}
        while(c>='0'&&c<='9'){num=num*10+c-'0';c=getchar();}
        return num*flag;
    }
    int main()
    {
        n=read();m=read();
        for(int i=1;i<=n;i++)
          mon[i]=read();
        for(int i=1;i<=m;i++)
        {
            a[i].tot=read();
            for(int j=1;j<=a[i].tot;j++)
              a[i].s[j]=read();
            a[i].t=read();
        }
        for(int t=1;t<=n;t++)
        {
            int flag=0;
            for(int i=1;i<=m;i++)
            {
                int sum=0,maxn=0;
                for(int j=1;j<=a[i].tot;j++)
                  sum+=mon[a[i].s[j]],maxn+=step[a[i].s[j]];
                if(sum<mon[a[i].t])
                {
                    step[a[i].t]=maxn+1;
                    mon[a[i].t]=sum;
                    flag=1;
                }
                if(sum==mon[a[i].t]&&maxn+1<step[a[i].t])
                  step[a[i].t]==maxn+1,flag=1;
            }
            if(!flag)break;
        }
        printf("%d %d",mon[n],step[n]);
        return 0;
    }
    View Code
  • 相关阅读:
    c++ range库
    差分数组
    简单比较一下C++中的引用和指针
    数字图像处理中一张常用图片
    内存池与内存块
    SmartPtr
    Allocator
    Java学习第12天
    Java学习第11天
    Java学习第10天
  • 原文地址:https://www.cnblogs.com/harden/p/5840231.html
Copyright © 2020-2023  润新知