Use a regular Multi-backpack to meet TLE.
The optimization is as follows:
// This question is mainly because cost and weight are the same, and only ask whether the number can be included. // set the DP array to bool type. If it can be reached, it is counted as 1; otherwise, it is 0. // The initial condition is DP [0] = 1; it indicates that 0 dollars can always generate ~ // The transfer equation is DP [I] | = DP [I-A [I]; which indicates the conditions for the total amount of money I can generate for all coins of the first I par value: // 1. for the front I-1 or I (corresponding to 01 backpack and full backpack respectively) All coins with a par value, you can make up the total I amount // or // 2. for all the coins with the front I-1 nominal value, you can make up the total I-A [I] amount of money // memory: 348 ktime: 2766 Ms !! # Include <iostream> # include <cstring> using namespace STD; const int maxn = 105; const int maxm = 100005; int A [maxn], C [maxn], V; bool DP [maxm]; void zeroonepack (INT cost) {for (INT I = V; I >= cost; I --) if (! DP [I]) DP [I] = DP [I-cost]; return;} void completepack (INT cost) {for (INT I = cost; I <= V; I ++) if (! DP [I]) DP [I] = DP [I-cost]; return;} void multiplepack (INT cost, int amount) {If (Cost * Amount> = V) completepack (cost); else {int K = 1; while (k <= Amount) {zeroonepack (K * cost); amount-= K; K * = 2 ;} zeroonepack (Amount * cost); Return ;}} int main () {int n, m; while (CIN> N> M & (n + M )) {for (INT I = 1; I <= N; I ++) CIN> A [I]; for (INT I = 1; I <= N; I ++) CIN> C [I]; memset (DP, 0, sizeof (DP); DP [0] = 1; V = m; int CNT = 0; for (INT I = 1; I <= N; I ++) {If (C [I]) multiplepack (A [I], C [I]);} for (INT I = 1; I <= m; I ++) {If (DP [I]) CNT ++;} cout <CNT <Endl ;} return 0 ;}
Although the memory is good, but the time is still long .. I have another Baidu optimization method:
// Memory: 460 ktime: 1172 Ms # include <cstdio> # include <cstring> using namespace STD; bool DP [100005]; int P [105]; short C [105]; short num [100005]; int main () {int I, j, n, m, CNT; while (scanf ("% d ", & N, & M), N + M) {for (I = 0; I <n; I ++) scanf ("% d", & P [I]); for (I = 0; I <n; I ++) scanf ("% HD", & C [I]); memset (DP, 0, sizeof (DP )); DP [0] = 1; CNT = 0; // as a full backpack, use another DP to limit the number of items to be taken, reduce the process of calling the function // is another optimization idea for multiple backpacks, beside binary for (I = 0; I <n; I ++) {Memset (Num, 0, sizeof (Num); For (j = P [I]; j <= m; j ++) {If (! DP [J] & DP [J-P [I] & num [J-P [I] <C [I]) // dual-line DP ah .. num also has the state transition equation {num [J] = num [J-P [I] + 1; // num [J] indicates the number of I coins selected when the total amount of money is J. DP [J] = 1; CNT ++ ;}}} printf ("% d \ n", CNT);} return 0 ;}
But the first few in... status...