/***Zoj 1013 Great Equipment
主要思路
遍历所有可能的携带方案组合(x, y, z)其中, x 为携带的第0中设备数量,
y为携带的第1种设备数量, z为携带的第2种设备数量。
使用Dynamic progromming 来计算可能的携带方案
****/
#include <cstdlib>
#include <iostream>
#include <cstring>
#define MAXN 101
#define MAXQUANTITY 501
using namespace std;
inline int maxSets(int x, int y, int z, int q[3])
{
x = x/q[0]; y = y/q[1]; z = z/q[2];
return x > y ? (y > z ? z : y) : (x > z ? z : x);
}
//前 i个车队带了x个第0种设备和 y个第1种设备后, 还能带的第2种设备数量
int f[2][MAXQUANTITY][MAXQUANTITY];
int main(int argc, char *argv[])
{
int n;
int w[3], s[3], d[3], q[3];
//商队能带的最大重量, 尺寸
int wt[MAXN], sz[MAXN];
//前i个车队带了x个第0种设备后 , 还能带的第1种设备数量
int a[MAXN][MAXQUANTITY];
int sx[MAXN];
int value;
int cases=1;
while (true)
{
cin>>n;
if (n == 0) break;
for (int i = 0; i < 3; i++)
cin>>w[i]>>s[i]>>d[i];
cin>>q[0]>>q[1]>>q[2];
cin>>value;
/*计算前i个车队能带的第0种设备数量 */
sx[0] = 0;
for (int i = 1; i <= n; i++)
{
cin>>wt[i]>>sz[i];
int x1, x2;
sx[i] = sx[i-1] +
(( x1 = wt[i]/w[0]) > (x2 = sz[i] / s[0]) ? x2 : x1);
}
//for (int i = 0; i <= n; i++
/*计算前 i个车队在带了x种第0种设备后, 还能带的第一种设备数量 */
memset(a[0], 0, sizeof(a[0]));
for (int i = 1; i <= n; i++)
{
for (int x = 0; x <= sx[i]; x++)
{
a[i][x] = 0;
//y: 第 i个车队带的第0种设备数量
int y = 0;
if (x > sx[i-1]) y = x - sx[i-1];
for (; y <= sx[i] - sx[i-1]; y++)
{
int x1, x2;
int num1 = ( x1 = (wt[i] - y*w[0])/w[1] ) > ( x2 = (sz[i] - y*s[0])/s[1] )
? x2 : x1;
if ( a[i-1][x-y] + num1 > a[i][x])
a[i][x] = num1 + a[i-1][x-y];
}
}
}
// for (int i = 0; i <= n; i++)
// {
// for (int x = 0; x <= sx[i]; x++)
// cout<<a[i][x]<<" ";
// cout<<endl;
// }
/*计算前i个车队在带了x种0设备, y种1设备后, 能带的2设备数量*/
// for (int x = 0; x < MAXQUANTITY; x++)
// for (int y = 0; y < MAXQUANTITY; y++)
f[0][0][0] = 0;
for (int i = 1; i <= n; i++)
{
for (int x = 0; x <= sx[i]; x++)
{
for (int y = 0; y <= a[i][x]; y++)
{
f[1][x][y] = 0;
int t0, t1;
int mx0 = ( t0 = wt[i]/w[0] ) > ( t1 = sz[i]/s[0] ) ? t1 : t0;
//x0 第i个车队带的0设备数量, x1第i个车队带的1设备数量
int x0 = 0;
//当x总数超过前i-1个车队能带的0设备能力时, 第i车队应当至少带:
if ( x > sx[i-1] ) x0 = x - sx[i-1];
for (; x0 <= mx0 && x0 <= x; x0++)
{
int mx1 = ( t0 = (wt[i] - x0*w[0])/w[1] ) > ( t1 = (sz[i] - x0*s[0])/s[1] )
? t1 : t0;
int x1 = 0;
if ( y > a[i-1][x - x0] ) x1 = y - a[i-1][x - x0];
for (; x1 <= mx1 && x1 <= y; x1++)
{
int mx2 = ( t0 = (wt[i] - x0*w[0] - x1*w[1])/w[2] )
> ( t1 = (sz[i] - x0*s[0] - x1*s[1])/s[2] ) ? t1 : t0;
if (f[1][x][y] < f[0][x-x0][y-x1] + mx2)
f[1][x][y] = f[0][x-x0][y-x1] + mx2;
// cout<<"x-x0 = "<<x - x0<<endl;
// cout<<"y-x1 ="<<y - x1<<endl;
// cout<<"f[1][x][y] = "<<f[1][x][y]<<endl;
// cout<<"f[0][x][y] = "<<f[0][x-x0][y-x1]<<endl;
}
}
}
}
for (int x = 0; x <= sx[i]; x++)
for (int y = 0; y <= a[i][x]; y++)
f[0][x][y] = f[1][x][y];
}
//cout<<"Here!/n";
//枚举遍历, 求最大值
int max = 0, mm, kk;
int xx, yy, zz;
//bool flag = value > q[0]*d[0]+q[1]*d[1]+q[1]*d[2];
//cout<<"sx[n]="<<sx[n]<<endl;
//cout<<"a[n][0] = "<<a[n][0]<<endl;
//cout<<f[0][0][0]<<endl;
for (int x = 0; x <= sx[n]; x++)
for (int y = 0; y <= a[n][x]; y++)
for (int z = 0; z <= f[0][x][y]; z++)
{
kk = maxSets(x, y, z, q);
xx = x - kk*q[0]; yy = y - kk*q[1];
zz = z - kk*q[2];
mm = xx*d[0] + yy*d[1] + zz*d[2] + kk*value;
if ( mm > max ) max = mm;
}
if (cases > 1) cout<<endl;
cout<<"Case "<<cases++<<": "<<max<<endl;
}
}
ZOJ 1013 Great Equipment ---- DP
最新推荐文章于 2021-03-27 04:55:12 发布