题目描述
有n种重量和价值分别为w[i],v[i]的物品,从这些物品中挑选总重量不超过W的物品,求挑出物品价值总和的最大值。在这里,每种物品可以挑选多次。 限制条件 1 <= n <=100 1<= w[i],v[i] <= 100 1<=W<=10000
输入
n
,w
w
[i
],v
[i
]
输出
价值总和的最大值
样例输入
3 7
3 4
4 5
2 3
样例输出
10
代码
#include
<algorithm
>
#include
<iostream
>
#include
<cstdio
>
using namespace std
;
const int
N = 1010;
int dp
[N][N];
int
W[N],V[N];
int
main()
{
int n
,m
;
scanf("%d%d",&n
,&m
);
for(int i
= 1;i
<=n
;i
++)
{
scanf("%d%d",&W[i
],&V[i
]);
}
for(int i
= 1;i
<=n
;i
++)
{
for(int j
= 0;j
<=m
;j
++)
{
for(int k
= 0;k
*W[i
]<=j
;k
++)
{
dp
[i
][j
] = max(dp
[i
][j
],dp
[i
-1][j
-k
*W[i
]]+k
*V[i
]);
}
}
}
printf("%d\n",dp
[n
][m
]);
return 0;
}
这个代码有三种循环,时间超限,然后想办法去掉k循环
f[i , j ] = max( f[i-1,j] , f[i-1,j-v]+w , f[i-1,j-2*v]+2*w , f[i-1,j-3*v]+3*w , .....)
f[i , j-v]= max( f[i-1,j-v] , f[i-1,j-2*v] + w , f[i-1,j-2*v]+2*w , .....)
由上两式,可得出如下递推关系:
f[i][j]=max(f[i,j-v]+w , f[i-1][j])
优化后的代码
#include
<algorithm
>
#include
<iostream
>
#include
<cstdio
>
using namespace std
;
const int
N = 1010;
int dp
[N][N];
int
W[N],V[N];
int
main()
{
int n
,m
;
scanf("%d%d",&n
,&m
);
for(int i
= 1;i
<=n
;i
++)
{
scanf("%d%d",&W[i
],&V[i
]);
}
for(int i
= 1;i
<=n
;i
++)
{
for(int j
= 0;j
<=m
;j
++)
{
dp
[i
][j
] = dp
[i
-1][j
];
if(j
>=W[i
])
{
dp
[i
][j
] = max(dp
[i
][j
],dp
[i
][j
-W[i
]]+V[i
]);
}
}
}
printf("%d\n",dp
[n
][m
]);
return 0;
}
还可以再优化一下
#include
<algorithm
>
#include
<iostream
>
#include
<cstdio
>
using namespace std
;
const int
N = 1010;
int dp
[N];
int
W[N],V[N];
int
main()
{
int n
,m
;
scanf("%d%d",&n
,&m
);
for(int i
= 1;i
<=n
;i
++)
{
scanf("%d%d",&W[i
],&V[i
]);
}
for(int i
= 1;i
<=n
;i
++)
{
for(int j
= W[i
];j
<=m
;j
++)
{
dp
[j
] = max(dp
[j
],dp
[j
-W[i
]]+V[i
]);
}
}
printf("%d\n",dp
[m
]);
return 0;
}
再将输入输出优化一下
#include
<algorithm
>
#include
<iostream
>
#include
<cstdio
>
using namespace std
;
const int
N = 1010;
int dp
[N];
int
main()
{
int n
,m
;
scanf("%d%d",&n
,&m
);
for(int i
= 1;i
<=n
;i
++)
{
int
W,V;
scanf("%d%d",&W,&V);
for(int j
= W;j
<=m
;j
++)
{
dp
[j
] = max(dp
[j
],dp
[j
-W]+V);
}
}
printf("%d\n",dp
[m
]);
return 0;
}