//no even number in the table void factor_using_table_odd(i64 n, IntPairVec& vpairs, const vector<int>& ftable) { vpairs.clear(); i64 n2 = 0; while( (n & 1) == 0){ n >>= 1; ++n2; } if(n2) vpairs.push_back(IntPair(2, n2)); assert( (n & 1) > 0); int np = (n-1) >> 1; int pwr = 0; int curr_fac = ftable[np]; while(curr_fac>1){ ++pwr; n /= curr_fac; np = (n-1) >> 1; while(curr_fac == ftable[np]){ ++pwr; n /= ftable[np]; np = (n-1) >> 1; } vpairs.push_back(IntPair(curr_fac, pwr)); curr_fac = ftable[np]; pwr = 0; } }
int theMin(vector <int> init, vector <int> grow, int H) { #define INIT(i) v[i].second #define GROW(i) v[i].first int N = init.size(); LL dp[52][52] = {0}; int i, j; IntPairVec v; for (i = 0; i < N; ++i) { v.push_back(IntPair(grow[i], init[i])); } sort(v.begin(), v.end()); int gsum = 0; for (i = 0; i < N; ++i) { // 切らない場合の合計値 dp[i + 1][0] = dp[i][0] + INIT(i); for (j = 1; j <= i; ++j) { // (i-1)まででj本切ってi番目が成長するのと // (i-1)までで(j-1)本切ってi番目を切るのの最小値 dp[i+1][j] = min(dp[i][j]+INIT(i)+GROW(i)*j, dp[i][j-1]+gsum); } // used for dp[N][N] dp[i+1][j] = dp[i][j-1] + gsum; gsum += GROW(i); } for (j = 0; j <= N; ++j) { // j本切った合計がH以下ならOK if (dp[N][j] <= H) { return j; } } return -1; }
//the factors are from small to large //first is prime number, second is power void factor_using_table(i64 n, IntPairVec& vpairs, const vector<int>& ftable) { vpairs.clear(); int pwr = 0; int curr_fac = ftable[n]; while(curr_fac>1){ ++pwr; n /= ftable[n]; while(curr_fac == ftable[n]){ ++pwr; n /= ftable[n]; } vpairs.push_back(IntPair(curr_fac, pwr)); curr_fac = ftable[n]; pwr = 0; } }