zoukankan      html  css  js  c++  java
  • 救命(洛谷 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
  • 相关阅读:
    Java实现 LeetCode 27 移除元素
    Java实现 LeetCode 26 删除排序数组中的重复项
    Java实现 LeetCode 26 删除排序数组中的重复项
    Java实现 LeetCode 26 删除排序数组中的重复项
    Java实现 LeetCode 25 K个一组翻转链表
    Java实现 LeetCode 25 K个一组翻转链表
    Java实现 LeetCode 25 K个一组翻转链表
    Java实现 LeetCode 24 两两交换链表中的节点
    Java实现 LeetCode 24 两两交换链表中的节点
    Java实现 LeetCode 24 两两交换链表中的节点
  • 原文地址:https://www.cnblogs.com/harden/p/5840231.html
Copyright © 2011-2022 走看看