zoukankan      html  css  js  c++  java
  • hihocoder #1270 建造基地

    传送门

    时间限制:10000ms
    单点时限:1000ms
    内存限制:256MB

    描述

    在遥远的未来,小Hi成为了地球联邦外空间联合开发工作组的一员,前往一颗新发现的星球开发当地的重金属资源。

    为了能够在当地生存下来,小Hi首先要建立一个基地。建立基地的材料可以直接使用当地的石材和富裕的重金属资源。基地建设分为N级,每一级都需要达成K的建设值后才能够完成建设,当前级别的建设值溢出后不会影响到下一级的建设。

    小Hi可以产出的重金属资源按照精炼程度分为M级,根据开采的数量和精炼的工艺,可以将获取精炼程度为第i级的重金属资源的成本量化为Ai

    在建设第1级基地时,一块精炼度为i的重金属可以提供Bi的建设值,此后基地的级别每提高一级,建设值将除以T并下取整(整除)。

    现给定N、M、K、T、A[]和B[],小Hi需要你帮助他计算他完成基地建设的最小成本。

    输入

    输入包含多组测试数据。

    输入的第一行为一个整数Q,表示测试数据的组数。

    每组测试数据的第一行为4个整数N、M、K和T,意义如前文所述。

    接下来的一行为M个整数,分别表示A1~AM

    接下来的一行为M个整数,分别表示B1~BM

    对于100%的数据,满足1<=N<=10,1<=M<=100,1<=K,T<=104

    对于100%的数据,满足Ai和Bi均为32位整型范围内的正整数

    对于100%的数据,满足1<=Q<=10

    输出

    对于每组测试数据,如果小Hi最终能够完成基地建设,则输出小Hi完成基地建设所需要的最小成本,否则输出“No Answer”。

    样例输入
    2
    2 2 2 2
    1 3
    1 2
    2 2 2 2
    1 2
    1 1
    
    样例输出
       8
       No Answer

    Solution:
    DP。
    各级基地的建设相互独立,建设某一级基地的最小成本是一个类多重背包问题:
    $dp[i][j]表示利用前i级重金属资源获得至少j建设值所需的最小成本,转移方程:$
    [dp[i][j]=min(dp[i-1][j], dp[i][j-b[i]]+a[i])]

    Implementation:
    由于DP状态中有“至少”二字,不能直接采用上面的转移方程(但这并不意味着它是错的),而是需要调整一下转移的方式(注意:是“方式”而非“方向”):
    $从前一状态推到后一状态, 即从dp[i][j]推到dp[i+1][j]和dp[i][min(j+b[i], K)].$
     
     
    #include <bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    
    const int M(105), K(1e4+5);
    LL dp[M][K], INF=1LL<<60;
    int a[M], b[M];
    
    void upd(LL &x, LL y){
        x=~x?min(x, y):y;
    }
    
    int main(){
        int T, n, m, k, t;
        for(cin>>T; T--; ){
            cin>>n>>m>>k>>t;
            for(int i=1; i<=m; i++) cin>>a[i];
            for(int i=1; i<=m; i++) cin>>b[i];
            LL ans=0;
            bool f=true;
            for(int i=0; i<n; i++){
                memset(dp, -1, sizeof(dp));
                for(int i=0; i<=m; i++) dp[i][0]=0;
                for(int i=0; i<=m; i++)
                    for(int j=0; j<=k; j++)
                        if(~dp[i][j]){
                            if(i<m) upd(dp[i+1][j], dp[i][j]);
                            if(i) upd(dp[i][min(k, j+b[i])], dp[i][j]+a[i]);
                        }
                if(~dp[m][k]) ans+=dp[m][k];
                else{f=false; break;}
                for(int i=1; i<=m; i++) b[i]/=t;
            }
            if(f) cout<<ans<<endl; else puts("No Answer");
        }
        return 0;
    }
  • 相关阅读:
    ubuntu 制做samba
    《Programming WPF》翻译 第4章 前言
    《Programming WPF》翻译 第4章 3.绑定到数据列表
    《Programming WPF》翻译 第4章 4.数据源
    《Programming WPF》翻译 第5章 6.触发器
    《Programming WPF》翻译 第4章 2.数据绑定
    《Programming WPF》翻译 第4章 1.不使用数据绑定
    《Programming WPF》翻译 第5章 7.控件模板
    《Programming WPF》翻译 第5章 8.我们进行到哪里了?
    《Programming WPF》翻译 第5章 5.数据模板和样式
  • 原文地址:https://www.cnblogs.com/Patt/p/5380548.html
Copyright © 2011-2022 走看看