POJ 1742多重リュック問題
2316 ワード
コイン1個あたりの重量をA[i]とし、数量はC[i]価格はA[i]とする.
dp(i,j)を定義するのは、前のiつの物品が容量jのリュックサックに入れられて得られる最大の価値である.
dp(n,m)を求めるだけです
dp(n,m)を求める過程で、dp(n,1)、dp(n,2)......dp(n,m-1)はすべてすでに求めました
dp(n,i)がiに等しいかどうかを見て、コインでiのものを買うことができるかどうかを判断することができます.
dp(i,j)を定義するのは、前のiつの物品が容量jのリュックサックに入れられて得られる最大の価値である.
dp(n,m)を求めるだけです
dp(n,m)を求める過程で、dp(n,1)、dp(n,2)......dp(n,m-1)はすべてすでに求めました
dp(n,i)がiに等しいかどうかを見て、コインでiのものを買うことができるかどうかを判断することができます.
#include
#include
#include
#include
#include
#include
#include
#define MAX_N 100005
#define INF 0x3f3f3f
using namespace std;
typedef long long int ll;
int dp[MAX_N];
int main()
{
//freopen("1.txt", "r", stdin);
int weight[MAX_N], value[MAX_N], num[MAX_N];
int n, m;
while (cin >> n >> m && n && m)
{
for (int i = 1; i <= n; i++)
{
scanf("%d", &weight[i]);
value[i] = weight[i];
}
for (int i = 1; i <= n; i++)
scanf("%d", &num[i]);
memset(dp, 0, sizeof(dp));
for (int i = 1; i <= n; i++)
{
if (weight[i] * num[i] >= m)
{
for (int j = weight[i]; j <= m; j++)
{
if (dp[j] < dp[j - weight[i]] + value[i])
dp[j] = dp[j - weight[i]] + value[i];
}
}
else
{
int k = 1;
while (k < num[i])
{
for (int j = m; j >= k * weight[i]; j--)
{
if (dp[j] < dp[j - k * weight[i]] + k * value[i])
dp[j] = dp[j - k * weight[i]] + k * value[i];
}
num[i] -= k;
k <<= 1;
}
for (int j = m; j >= num[i] * weight[i]; j--)
{
if (dp[j] < dp[j - num[i] * weight[i]] + num[i] * value[i])
dp[j] = dp[j - num[i] * weight[i]] + num[i] * value[i];
}
}
}
int ans = 0;
for (int i = 1; i <= m; i++)
{
if (dp[i] == i)
ans++;
}
printf("%d
", ans);
}
return 0;
}