Question: give several coins with different denominations and the corresponding number to see if each nominal value in 1-m can be obtained.
Analysis: Obviously, there are multiple knapsack problems. It must be full. In addition, 1-m traversal and counting are not under pressure ~
Code:
[Cpp] # include <iostream>
Using namespace std;
Int MIN_INT = (~ (Unsigned (-1)> 1 ));
Int F [100001];
Int A [101];
Int C [101];
Int max (int a, int B)
{
Return a> B? A: B;
}
Void ZeroOnePack (int cost, int weight, int V)
{
For (int v = V; v> = cost; -- v)
F [v] = max (F [v], F [v-cost] + weight );
}
Void CompletePack (int cost, int weight, int V)
{
For (int v = cost; v <= V; ++ v)
F [v] = max (F [v], F [v-cost] + weight );
}
Void MultiPack (int cost, int weight, int V, int amount)
{
If (cost * amount> = V ){
CompletePack (cost, weight, V );
Return;
}
Int k = 1;
While (k <amount ){
ZeroOnePack (cost * k, weight * k, V );
Amount-= k;
K * = 2;
}
ZeroOnePack (cost * amount, weight * amount, V );
}
Int main (int argc, char ** argv)
{
Int n, m, count;
While (cin> n> m) & (m + n )){
For (int I = 1; I <= n; ++ I)
Cin> A [I];
For (int I = 1; I <= n; ++ I)
Cin> C [I];
Count = 0;
For (int V = 1; V <= m; ++ V ){
F [0] = 0;
For (int I = 1; I <= m; ++ I)
F [I] = MIN_INT;
For (int I = 1; I <= n; ++ I)
MultiPack (A [I], A [I], V, C [I]);
If (F [V] = V)
++ Count;
}
Cout <count <endl;
}
System ("pause ");
Return 0;
}
# Include <iostream>
Using namespace std;
Int MIN_INT = (~ (Unsigned (-1)> 1 ));
Int F [100001];
Int A [101];
Int C [101];
Int max (int a, int B)
{
Return a> B? A: B;
}
Void ZeroOnePack (int cost, int weight, int V)
{
For (int v = V; v> = cost; -- v)
F [v] = max (F [v], F [v-cost] + weight );
}
Void CompletePack (int cost, int weight, int V)
{
For (int v = cost; v <= V; ++ v)
F [v] = max (F [v], F [v-cost] + weight );
}
Void MultiPack (int cost, int weight, int V, int amount)
{
If (cost * amount> = V ){
CompletePack (cost, weight, V );
Return;
}
Int k = 1;
While (k <amount ){
ZeroOnePack (cost * k, weight * k, V );
Amount-= k;
K * = 2;
}
ZeroOnePack (cost * amount, weight * amount, V );
}
Int main (int argc, char ** argv)
{
Int n, m, count;
While (cin> n> m) & (m + n )){
For (int I = 1; I <= n; ++ I)
Cin> A [I];
For (int I = 1; I <= n; ++ I)
Cin> C [I];
Count = 0;
For (int V = 1; V <= m; ++ V ){
F [0] = 0;
For (int I = 1; I <= m; ++ I)
F [I] = MIN_INT;
For (int I = 1; I <= n; ++ I)
MultiPack (A [I], A [I], V, C [I]);
If (F [V] = V)
++ Count;
}
Cout <count <endl;
}
System ("pause ");
Return 0;
}
Okay ~ POJ's system says TLE ~ One meter of tragedy ~ After reading discuss, the question is not that simple. O (V * Σ log n [I]) cannot be used ~ Okay, optimization ~
Further analysis:
In fact, the above program finds the value of F [V], which is not required theoretically. We are concerned about whether F [V] is equal to V. Here we will optimize:
Change int F [100001] To bool F [100001], and store whether F [V] is equal to V
ZeroOnePack and CompletePack can be modified
Void ZeroOnePack (int cost, int weight, int V)
{
For (int v = V; v> = cost; -- v)
F [v] | = F [v-cost];
}
Void CompletePack (int cost, int weight, int V)
{
For (int v = cost; v <= V; ++ v)
F [v] | = F [v-cost];
}
F [v] | = F [v-cost] directly or using 0, 1 indicates whether the price has been listed in the final code:
# Include <iostream> [cpp] using namespace std;
Bool F [100001];
Int A [101];
Int C [101];
Int max (int a, int B)
{
Return a> B? A: B;
}
Void ZeroOnePack (int cost, int weight, int V)
{
For (int v = V; v> = cost; -- v)
F [v] | = F [v-cost];
}
Void CompletePack (int cost, int weight, int V)
{
For (int v = cost; v <= V; ++ v)
F [v] | = F [v-cost];
}
Void MultiPack (int cost, int weight, int V, int amount)
{
If (cost * amount> = V ){
CompletePack (cost, weight, V );
Return;
}
Int k = 1;
While (k <amount ){
ZeroOnePack (cost * k, weight * k, V );
Amount-= k;
K * = 2;
}
ZeroOnePack (cost * amount, weight * amount, V );
}
Int main (int argc, char ** argv)
{
Int n, m;
While (cin> n> m) & (m + n )){
For (int I = 1; I <= n; ++ I)
Cin> A [I];
For (int I = 1; I <= n; ++ I)
Cin> C [I];
F [0] = 1;
For (int I = 1; I <= m; ++ I)
F [I] = 0;
For (int I = 1; I <= n; ++ I)
MultiPack (A [I], A [I], m, C [I]);
Int ans = 0;
For (int I = 1; I <= m; ++ I)
Ans + = F [I];
Cout <ans <endl;
}
System ("pause ");
Return 0;
}
2329MS dangerous ~
Using namespace std;
Bool F [100001];
Int A [101];
Int C [101];
Int max (int a, int B)
{
Return a> B? A: B;
}
Void ZeroOnePack (int cost, int weight, int V)
{
For (int v = V; v> = cost; -- v)
F [v] | = F [v-cost];
}
Void CompletePack (int cost, int weight, int V)
{
For (int v = cost; v <= V; ++ v)
F [v] | = F [v-cost];
}
Void MultiPack (int cost, int weight, int V, int amount)
{
If (cost * amount> = V ){
CompletePack (cost, weight, V );
Return;
}
Int k = 1;
While (k <amount ){
ZeroOnePack (cost * k, weight * k, V );
Amount-= k;
K * = 2;
}
ZeroOnePack (cost * amount, weight * amount, V );
}
Int main (int argc, char ** argv)
{
Int n, m;
While (cin> n> m) & (m + n )){
For (int I = 1; I <= n; ++ I)
Cin> A [I];
For (int I = 1; I <= n; ++ I)
Cin> C [I];
F [0] = 1;
For (int I = 1; I <= m; ++ I)
F [I] = 0;
For (int I = 1; I <= n; ++ I)
MultiPack (A [I], A [I], m, C [I]);
Int ans = 0;
For (int I = 1; I <= m; ++ I)
Ans + = F [I];
Cout <ans <endl;
}
System ("pause ");
Return 0;
}
2329MS dangerous ~