The trouble of Xiaoqian
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1712 Accepted Submission(s): 594
And now , Xiaoqian wants to buy T (1 ≤ T ≤ 10,000) cents of supplies. The currency system has N (1 ≤ N ≤ 100) different coins, with values V1, V2, ..., VN (1 ≤ Vi ≤ 120). Xiaoqian is carrying C1 coins of value V1, C2 coins of value V2, ...., and CN coins of value VN (0 ≤ Ci ≤ 10,000). The shopkeeper has an unlimited supply of all the coins, and always makes change in the most efficient manner .But Xiaoqian is a low-pitched girl , she wouldn’t like giving out more than 20000 once.
Line 1: Two space-separated integers: N and T.
Line 2: N space-separated integers, respectively V1, V2, ..., VN coins (V1, ...VN)
Line 3: N space-separated integers, respectively C1, C2, ..., CN
The end of the input is a double 0.
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int inf = 0x3f3f3f3f;
const int MAX = 105;
int main()
{
int N, T, v[MAX], c[MAX], sum, ans, kase = 1;
int dp1[20005], dp2[20005];//用揹包保存需要貨幣的數量
while(scanf("%d %d", &N, &T) && N+T)
{
sum = 0;
ans = inf;
memset(dp1, 0x3f, sizeof(dp1));
memset(dp2, 0x3f, sizeof(dp2));
dp1[0] = dp2[0] = 0;
for(int i = 0;i < N; ++i) scanf("%d", &v[i]);
for(int i = 0;i < N; ++i)
{
scanf("%d", &c[i]);
sum += c[i]*v[i];
}
for(int i = 0;i < N; ++i)//商家是完全揹包
for(int j = v[i];j <= sum; ++j)
dp1[j] = min(dp1[j], dp1[j-v[i]]+1);
for(int i = 0;i < N; ++i)//Xiaoqian是多重揹包
{
for(int k = 1;k <= c[i]; k*=2)
{
for(int j = sum;j >= k*v[i]; --j)
dp2[j] = min(dp2[j], dp2[j-k*v[i]]+k);
c[i] -= k;
}
for(int j = sum;j >= c[i]*v[i]; --j)
dp2[j] = min(dp2[j], dp2[j-c[i]*v[i]]+c[i]);
}
for(int i = T;i <= sum; ++i)
{
if(dp1[i] ==inf || dp2[i-T] == inf) continue;
ans = min(ans, dp2[i] + dp2[i-T]);
}
printf("Case %d: ", kase++);
if(ans == inf) cout << -1 << endl;
else cout << ans << endl;
}
return 0;
}