hdu6007 Mr. Panda and Crystal 最短路+完全背包

/**
题目:hdu6007 Mr. Panda and Crystal
链接:http://acm.hdu.edu.cn/showproblem.php?pid=6007
题意:魔法师有m能量,有n种宝石,有些宝石给定了用魔法变出它需要的能量,以及该宝石可以卖出的价钱。
有些宝石没有给出,给出k个方程,表示某些宝石可以通过另外一些宝石合成。
求魔法师最多可以卖出多少钱。

思路:
处理方程,最短路求出所有的宝石用能量变出的最小能量值。
然后完全背包。

*/

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<map>
#include<vector>
#include<cstring>
using namespace std;
typedef pair<int,int> P;
typedef long long LL;
const int N = 205;
const int inf = 0x3f3f3f3f;

int cost[N], price[N];
struct node
{
    int goal;
    vector<P> v;
}eq[N];
int dp[10004];
int main()
{
    int cas = 1, T, n, m, k;
    cin>>T;
    while(T--)
    {
        scanf("%d%d%d",&m,&n,&k);
        int flag;
        for(int i = 1; i <= n; i++){
            scanf("%d",&flag);
            if(flag==0){
                cost[i] = -1;
                scanf("%d",&price[i]);
            }else
            {
                scanf("%d%d",&cost[i],&price[i]);
            }
        }
        int x, y;
        for(int i = 1; i <= k; i++) eq[i].v.clear();
        for(int i = 1; i <= k; i++){
            scanf("%d%d",&x,&y);
            eq[i].goal = x;
            int u, vv;
            for(int j = 1; j <= y; j++){
                scanf("%d%d",&u,&vv);
                eq[i].v.push_back(P(u,vv));
            }
        }
        while(1)
        {
            int flag = 1;
            for(int i = 1; i <= k; i++){
                int sign = 1;
                int sum = 0;
                for(int j = 0; j < (int)(eq[i].v.size()); j++){
                    P p = eq[i].v[j];
                    if(cost[p.first]==-1){
                        sign = 0; break;
                    }else
                    {
                        sum += cost[p.first]*p.second;
                        if(sum>m){///完全背包,最多m容量,所以超过m的能量花费,都不会被使用。这样避免溢出。
                            sum = m+1; break;
                        }
                    }
                }
                if(sign){
                    if(cost[eq[i].goal]!=-1){
                        if(cost[eq[i].goal]>sum){
                            cost[eq[i].goal] = sum;
                            flag = 0;
                        }
                    }else
                    {
                        cost[eq[i].goal] = sum;
                        flag = 0;
                    }
                }
            }
            if(flag) break;
        }
        memset(dp, 0, sizeof dp);
        for(int i = 1; i <= n; i++){
            if(cost[i]==-1) continue;
            for(int j = cost[i]; j <= m; j++){
                dp[j] = max(dp[j],dp[j-cost[i]]+price[i]);
            }
        }
        printf("Case #%d: %d\n",cas++,dp[m]);
    }
    return 0;
}
时间: 2024-08-26 02:28:24

hdu6007 Mr. Panda and Crystal 最短路+完全背包的相关文章

Mr. Panda and Crystal HDU - 6007 最短路+完全背包

题目:题目链接 思路:不难看出,合成每个宝石需要消耗一定的魔力值,每个宝石有一定的收益,所以只要我们知道每个宝石合成的最小花费,该题就可以转化为一个背包容量为初始魔力值的完全背包问题,每个宝石的最小花费可以用dijkstra跑一遍最短路算出,路径长度用合成花费表示. AC代码: 1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <cstring> 5 #in

hdu 3339(最短路+01背包)

In Action Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 5135    Accepted Submission(s): 1710 Problem Description Since 1945, when the first nuclear bomb was exploded by the Manhattan Project t

HDU 3339 In Action【最短路+01背包模板/主要是建模看谁是容量、价值】

 Since 1945, when the first nuclear bomb was exploded by the Manhattan Project team in the US, the number of nuclear weapons have soared across the globe. Nowadays,the crazy boy in FZU named AekdyCoin possesses some nuclear weapons and wanna destroy

[acm/icpc2016ChinaFinal][CodeforcesGym101194] Mr. Panda and Fantastic Beasts

地址:http://codeforces.com/gym/101194 题目:略 思路: 这题做法挺多的,可以sam也可以后缀数组,我用sam做的. 1.我自己yy的思路(瞎bb的) 把第一个串建立sam,然后让其他串在上面跑. 每走到一个位置p,当前长度为num,就代表这个endpos集合里的长度小于等于num的字符串是被包含了,同时parent树的所有祖先节点也要标记为被包含. 这一步的具体做法是:用一个mi数组表示到达该节p点时的长度大于mi[p]时,才算未被包含(到达长度指的是从root

Gym 101194F Mr. Panda and Fantastic Beasts

#include<bits/stdc++.h> using namespace std; #define ms(arr,a) memset(arr,a,sizeof arr) #define debug(x) cout<<"< "#x" = "<<x<<" >"<<endl const int maxn=4e5; const int INF=0x3f3f3f3f; char

Gym 101194C / UVALive 7899 - Mr. Panda and Strips - [set][2016 EC-Final Problem C]

题目链接: http://codeforces.com/gym/101194/attachments https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=5921 题意: 一个长度为 $N$ 的序列,要求选出两段不重叠的区间,要求两个区间包含的元素均互不相同,求两段区间的长度和最大为多少. 题解: (主要参考https://blo

【费用流】 ICPC 2016 China Final J. Mr.Panda and TubeMaster

表示“必须选”的模型 题目大意 题目分析 一个格子有四种方式看上去很难处理.将横竖两个方向分开考虑,会发现:因为收益只与相邻格子是否连通有关,所以可以将一个格子拆成表示横竖两个方向的,互相独立的点. 上图的格子里四个方向红边表示的就是一个格子的可能方向:拆点后所连蓝边的容量为1,费用即为连通两个格子的收益. 但是这样建图不能够表示某些格子必须要选. 考虑一个格子如果被选择了会发生什么:因为每个格子都处在环上,那么被选择的网格一定可以通过其他节点走到汇点.这意味着一个格子拆成的两个节点之间的边就可

In Action(最短路+01背包)

In Action Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 4764    Accepted Submission(s): 1569 Problem Description Since 1945, when the first nuclear bomb was exploded by the Manhattan Project t

hdu3339 In Action 最短路+01背包

//有n个电站,每一个电站能提供不同的power, //所有tank从0点出发,停在该电站就代表摧毁了该电站,tank从电站到电站之间需要耗费能量 //现在有无穷的tank,问最少需要耗费多少油能够摧毁一半以上的power //先用dijkstra求得到每个点的dis[i] //然后用一个01背包得到答案 #include<cstdio> #include<cstring> #include<iostream> using namespace std ; const i