潜水员--二维费用背包

一本通OJ 1271

潜水员--二维费用背包_第1张图片

题目分析:

  • 定义 f [ i ] [ j ] f[i][j] f[i][j]表示在满足氧气 i i i升,氮气 j j j升的限制条件下的最小气缸重量
  • 边界: f [ i ] [ j ] = I N F f[i][j]=INF f[i][j]=INF, f [ 0 ] [ 0 ] = 0 f[0][0]=0 f[0][0]=0
  • 状态转移方程: f [ i + a [ k ] ] [ j + b [ k ] ] = m i n ( f [ i + a [ k ] ] [ j + b [ k ] ] , f [ i ] [ j ] + w [ k ] ) f[i+a[k]][j+b[k]]=min(f[i+a[k]][j+b[k]],f[i][j]+w[k]) f[i+a[k]][j+b[k]]=min(f[i+a[k]][j+b[k]],f[i][j]+w[k])
  • 注意:要判断i+a[k]若大于n,则为n;氮气同理

Code:

#include 
using namespace std;
#define maxn 100
#define maxm 100
#define maxk 1100
int k,n,m,f[maxn][maxm],w[maxk],a[maxk],b[maxk];

inline void init_() {
     
	freopen("a.txt","r",stdin);
}

inline int read_() {
     
	int x=0,f=1;
	char c=getchar();
	while(c<'0'||c>'9') {
     
		if(c=='-') f=-1;
		c=getchar();
	}
	while(c>='0'&&c<='9') {
     
		x=(x<<3)+(x<<1)+c-'0';
		c=getchar();
	}
	return x*f;
}

inline void clean_() {
     
	memset(f,0x3f,sizeof(f));
	f[0][0]=0;
}

int pd_(int x,int y,int z) {
     
	if(x+y>=z) return z;
	else return x+y;
}

void readda_() {
     
	clean_();
	n=read_();m=read_();
	k=read_();
	for(int i=1;i<=k;++i) {
     
		a[i]=read_();b[i]=read_();w[i]=read_();
	}
	for(int i=1;i<=k;++i) {
     
		for(int j=n;j>=0;--j) {
     
			for(int p=m;p>=0;--p) {
     
				int fj=pd_(j,a[i],n);
				int fp=pd_(p,b[i],m);
				f[fj][fp]=min(f[fj][fp],f[j][p]+w[i]);
			}
		}
	}
	printf("%d",f[n][m]);
}

int main() {
     
	init_();
	readda_();
	return 0;
}

你可能感兴趣的:(二维费用背包,二维费用背包)