• 新魔法药水


    题目描述

    商店里有N种药水,每种药水都有一个售价和回收价。小S攒了V元钱,还会M种魔法,可以把一些药水合成另一种药水。他一天可以使用K次魔法,问他一天最多赚多少钱?

    输入输出格式

    输入格式:

    第一行四个数N、M、V、K

    接下来N行,每行两个数,表示药水的售价和回收价。

    接下来M行,每行若干个数,第一个数表示魔法的成品,第二个数是原料的种数,接下来为各种原料的编号

    输出格式:

    一个数,表示小S的最大利润

    输入输出样例

    输入样例#1:

    4 2 6 3
    1 0
    1 0
    5 3
    20 15
    3 2 1 2
    4 3 1 2 3

    输出样例#1:

    12

    说明

    N<=60 M<=240

    V<=1000

    k<=30


    就是个背包,但是挺麻烦的

    跟昊哥一块搞的

    先预处理出(v[i][j])表示使用j次魔法后变成第i个物品的花费

    这可以用分层 + 背包来做

    就是一层一层的更新

    求出 v 数组以后直接简单背包一下就好辣

    #include<vector>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    const int M = 245 ;
    const int N = 1005 ;
    const int INF = 1e9 + 7 ;
    using namespace std ;
    inline int read() {
        char c = getchar() ; int x = 0 , w = 1 ;
        while(c>'9'||c<'0') { if(c=='-') w = -1 ; c = getchar() ; }
        while(c>='0'&&c<='9') { x = x*10+c-'0' ; c = getchar() ; }
        return x*w ;
    }
    
    int n , m , W , tot	;
    int val[M] , cost[M] ;
    int v[M][M] , res[M] ;
    int temp[M][M] ;
    vector < int > p[M] ;
    int f[N][M >> 2] ;
    inline void Update(int t , int m) {
        memset(temp , 63 , sizeof(temp)) ;
        temp[0][0] = 0 ;
        for(int i = 0 ; i <= m ; i ++)
            for(int j = 1 , u ; j < p[t].size() ; j ++) {
                u = p[t][j] ;
                for(int k = 0 ; k <= i ; k ++) {
                    temp[j][i] = min(temp[j][i] , temp[j - 1][i - k] + v[u][k]) ;
                }
            }
        v[res[t]][m + 1] = min( v[res[t]][m + 1] , temp[p[t].size() - 1][m] ) ;
        for(int i = m + 1 ; i <= tot ; i ++) 
            v[res[t]][i] = min(v[res[t]][i] , v[res[t]][m + 1]) ;
    }
    int main() {
        n = read() ; m = read() ; W = read() ; tot = read() ;
        for(int i = 1 ; i <= n ; i ++) {
            val[i] = read() ;
            cost[i] = read() ;
            for(int j = 0 ; j <= tot ; j ++)
                v[i][j] = val[i] ;
        }
        for(int i = 1 , x , Num ; i <= m ; i ++) {
            res[i] = read() ; Num = read() ; 
            p[i].push_back(0) ;
            while(Num -- ) {
                x = read() ;
                p[i].push_back(x) ;
            }
        }
        for(int i = 1 ; i <= tot ; i ++) // i表示使用i次魔法 
            for(int j = 1 ; j <= m ; j ++) // 第j种魔法 
            	Update(j , i - 1) ;
    // f[i][j] 表示花i元使用j次魔法的收益
    // v[i][j] 表示第i个物品使用j次魔法的花费 
        for(int i = 1 ; i <= W ; i ++)
            for(int j = 0 ; j <= tot ; j ++)
            	for(int k = 1 ; k <= n ; k ++)
            	    for(int l = 0 ; l <= j ; l ++)
            	        if(i - v[k][l] >= 0)
                            f[i][j] = max(f[i][j] , f[i - v[k][l]][j - l] + (cost[k] - v[k][l]) ) ;
        cout << f[W][tot] << endl ;
        return 0 ;
    }
    
  • 相关阅读:
    ubuntu 启动 重启 停止 apache
    /usr/bin/env: php: No such file or directory 【xunsearch demo项目体验】【已解决】
    安装mezzanine时报:storing debug log for failure【已解决】
    redhat 安装 setuptools【成功】
    SnowNLP:一个处理中文文本的 Python 类库[转]
    Android 了解1G 2G 3G 知识
    Android-体系架构
    Android-bindService远程服务(Aidl)-初步
    Android-SDCard外部存储文件读写
    Android-文件模式
  • 原文地址:https://www.cnblogs.com/beretty/p/9671206.html
Copyright © 2020-2023  润新知