Codevs 5056 潜水员

5056 潜水员
时间限制: 1 s
空间限制: 128000 KB
题目等级 : 黄金 Gold
题目描述 Description
潜水员为了潜水要使用特殊装备。他有一个带两种气体的气缸:一个为氮气,一个为氧气。让潜水员下潜的深度需要各种数量的氧和氮。潜水员有一定数量的气缸。每个气缸都有重量和气体容量。潜水员为了完成他的工作需要特定的氧和氮。他完成工作所需气缸的总重最低限度是多少?
例如:潜水员有5个气缸。每行有三个数字为:氧、氮的量(升)和气缸的重量:
3 36 120
10 25 129
5 50 250
1 45 130
4 20 119
如果潜水员需要5升的氧和60升的氮则总重的最小值为249(1,2或4,5号气缸)。
你的任务就是计算潜水员为了完成他的工作需要的气缸的重量的最低值。
输入描述 Input Description
第一行有2个整数m,n(1<=m<=21,1<=n<=79)。它们表示氧、氮各自需要的量。
第二行为整数k(1<=k<=1000)表示气缸的个数。
此后的k行,每行包括ai,bi,ci(1<=ai<=21,1<=bi<=79,1<=ci<=800)3整数。这些各自是:第i个气缸里的氧和氮的容量及气缸重量。
输出描述 Output Description
仅一行,包含一个整数,为潜水员完成工作所需气缸的重量总和的最低值。
样例输入 Sample Input
5 60
5
3 36 120
10 25 129
5 50 250
1 45 130
4 20 119
样例输出 Sample Output
249
数据范围及提示 Data Size & Hint
1<=m<=21,1<=n<=79
1<=k<=1000
1<=ai<=21,1<=bi<=79,1<=ci<=800

/*
恶心写法.
试了好几次才过. 
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#define MAXN 1001
using namespace std;
int f[MAXN][MAXN],w[MAXN],v1[MAXN],v2[MAXN],m,K,n,ans;
int read()
{
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9') {if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9') x=x*10+ch-48,ch=getchar();
    return x*f;
}
int main()
{
    memset(f,127/3,sizeof(f));ans=f[0][0];
    m=read();K=read();n=read();
    for(int i=1;i<=n;i++)
      v1[i]=read(),v2[i]=read(),w[i]=read();
    f[0][0]=0;
    for(int i=1;i<=n;i++)
      for(int j=20*m;j>=v1[i];j--)
        for(int k=20*K;k>=v2[i];k--)
          f[j][k]=min(f[j][k],f[j-v1[i]][k-v2[i]]+w[i]);
    for(int i=m;i<=20*m;i++)
      for(int j=K;j<=20*K;j++)
        ans=min(ans,f[i][j]);
    printf("%d",ans);
    return 0;
}
/*
二维费用背包.
我们不妨将状态由i向i+1转移.
因为题目中对m和k只有下限的要求.
考虑到更优的状态可能在j>=m,k>=K的状态里.
so转移的时候我们把j>=m,k>=K的状态放到f[m][K]里. 
因为这些状态是合法的并且无上限要求.
即x=j+v1[i],y=k+v2[i];
if(x>=m) x=m;if(y>=K) y=K;
f[x][y]=min(f[j][k]+w[i],f[x][y]);
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#define MAXN 1001
using namespace std;
int f[MAXN][MAXN],w[MAXN],v1[MAXN],v2[MAXN],m,K,n,ans;
int read()
{
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9') {if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9') x=x*10+ch-48,ch=getchar();
    return x*f;
}
int main()
{
    memset(f,127/3,sizeof(f));ans=f[0][0];
    m=read();K=read();n=read();
    for(int i=1;i<=n;i++)
      v1[i]=read(),v2[i]=read(),w[i]=read();
    f[0][0]=0;
    for(int i=1;i<=n;i++)
      for(int j=m;j>=0;j--)
        for(int k=K;k>=0;k--)
        {
            int x=j+v1[i],y=k+v2[i];
            if(x>=m) x=m;
            if(y>=K) y=K;
            f[x][y]=min(f[j][k]+w[i],f[x][y]);
        }
    printf("%d",f[m][K]);
    return 0;
}
原文地址:https://www.cnblogs.com/nancheng58/p/6070765.html