• RQNOJ 202 奥运火炬登珠峰:01背包


    题目链接:https://www.rqnoj.cn/problem/202

    题意:

      登珠峰需要携带a(L)O2和t(L)N2。

      有n个气缸可供选择。其中第i个气缸能装下a[i](L)O2和t[i](L)N2,气缸重量为w[i]。

      问你在满足需求的前提下,最小的气缸总重量为多少。

    题解:

      二重01背包。

      表示状态:

        dp[i][j][k]表示考虑到第i个气缸(还没选),已经能装下j(L)O2和k(L)N2。

        dp[i][j][k] = 此时的最小总重量

      找出答案:

        min dp[i][j][k] (j>=a && k>=t)

        (气缸编号为0~n-1)

      如何转移:

        由于此题与传统背包的区别为:氧气和氮气的容量需要大于等于所需体积。

        所以顺推。

        now: dp[i][j][k]

        dp[i+1][j][k] = max dp[i][j][k] (不选)

        dp[i+1][j+a[i]][k+t[i]] = max dp[i][j][k] + w[i]

     

      注:数据较水,可以不用考虑氧气拿的很少不够需求,而氮气大大超出需求的极端情况。

    AC Code:

    // state expression:
    // dp[i][j][k] = min weight of cylinders
    // i: considering ith cylinder
    // j: O2
    // k: N2
    //
    // find the answer:
    // min dp[n][>O2][>N2]
    //
    // transferring:
    // now: dp[i][j][k]
    // dp[i+1][j][k] = min dp[i][j][k]
    // dp[i+1][j+co2[i]][k+cn2[i]] = min dp[i][j][k] + w[i]
    //
    // bound:
    // dp[0][0][0] = 0
    // others = -1
    
    #include <iostream>
    #include <stdio.h>
    #include <string.h>
    #define MAX_N 2005
    #define MAX_O2 50
    #define MAX_N2 170
    #define INF 10000000
    
    using namespace std;
    
    int n;
    int ans;
    int o2,n2;
    int co2[MAX_N];
    int cn2[MAX_N];
    int w[MAX_N];
    int dp[MAX_N][MAX_O2][MAX_N2];
    
    void read()
    {
        cin>>o2>>n2>>n;
        for(int i=0;i<n;i++)
        {
            cin>>co2[i]>>cn2[i]>>w[i];
        }
    }
    
    void solve()
    {
        ans=INF;
        memset(dp,-1,sizeof(dp));
        dp[0][0][0]=0;
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<=o2;j++)
            {
                for(int k=0;k<=n2;k++)
                {
                    if(dp[i][j][k]!=-1)
                    {
                        if(dp[i+1][j][k]==-1 || dp[i+1][j][k]>dp[i][j][k])
                        {
                            dp[i+1][j][k]=dp[i][j][k];
                        }
                        if(dp[i+1][j+co2[i]][k+cn2[i]]==-1 || dp[i+1][j+co2[i]][k+cn2[i]]>dp[i][j][k]+w[i])
                        {
                            dp[i+1][j+co2[i]][k+cn2[i]]=dp[i][j][k]+w[i];
                            if(j+co2[i]>=o2 && k+cn2[i]>=n2) ans=min(ans,dp[i+1][j+co2[i]][k+cn2[i]]);
                        }
                        if(j>=o2 && k>=n2) ans=min(ans,dp[i][j][k]);
                    }
                }
            }
        }
    }
    
    void print()
    {
        cout<<ans<<endl;
    }
    
    int main()
    {
        read();
        solve();
        print();
    }

     

  • 相关阅读:
    encodeURIcomponent编码和ASP.NET之间编码转换
    android入门学习一 基本概念
    Acvityity 的生命周期
    Android中ADT插件的安装
    控件必须放在具有 runat=server 的窗体标记内 错误解决解决方法
    AspNetPager 重写UrlRewriting配置示例
    将字符串按指定长度换行的一个C#方法
    [添砖加瓦]:ExtJS+WCF+LINQ打造全功能Grid
    C#中判断字符是否为中文
    Asp.net中防止用户多次登录的方法
  • 原文地址:https://www.cnblogs.com/Leohh/p/7435322.html
Copyright © 2020-2023  润新知