srm565 div1
2013-01-12 17:11 macaroniz 阅读(146) 评论(0) 收藏 举报250pt
很简单的dp,没有什么好说的。
#define N 51 #define MAXPRICE 102 class MonstersValley { public: long long dp[N][MAXPRICE]; long long maxx(long long a,long long b) { if(a < b) return b; return a; } int minimumPrice(vector<long long> dread, vector <int> price) { int n = dread.size(); memset(dp,0xff,sizeof dp); dp[0][0] = 0; for(int i = 1;i <= n;i++) { for(int p = 0;p <= n*2+1;p++) { if(dp[i-1][p] != -1 && dp[i-1][p] >= dread[i-1]) dp[i][p] = dp[i-1][p]; int v = p - price[i-1]; if(v >= 0 && dp[i-1][v] != -1) dp[i][p] = maxx(dp[i][p],dp[i-1][v] + dread[i-1]); //printf("v:%d dp[i-1][v]:%I64d i:%d p:%d dp:%I64d\n",v,dp[i-1][v],i,p,dp[i][p]); } } for(int p = 0;p <= n*2+1;p++) if(dp[n][p] >= dread[n-1]) return p; } };
500pt
看出来这题其实就是个nim游戏的变种,并且对于每个数字,石子数(操作数)实际上就是他的质因数个数(若X = p1^n1 * p2 ^ n2.... ,p1,p2,..pn都是质数,质因数个数就是n1+n2+...)即可。
有个难点在于如何快速的求出sigma nim(x),详细的部分可以看程序。
int nim[1000000]; int val[1000000]; class TheDivisionGame { public: vector<int> prime; int facNum(int L,int R) { memset(nim,0,sizeof nim); for(int i = L;i <= R;i++) val[i-L] = i; for(int i = 2;i <= 100000;i++) for(int j = L/i*i;j <= R;j+=i) if(j >= L) { while(val[j - L] % i == 0) { nim[j - L]++; val[j - L] /= i; } } for(int i = L;i <= R;i++) if(val[i - L] != 1) nim[i - L]++; return 0; } long long countWinningIntervals(int L, int R) { long long ans = 0; map<int,int> hash; facNum(L,R); int sumNim = 0; for(int i = L;i <= R;i++) { sumNim ^= nim[i-L]; ans += hash[sumNim]; if(sumNim == 0) ans++; hash[sumNim]++; } return 1ll*(1 + R-L + 1) * (R - L + 1) / 2 - ans; } };
浙公网安备 33010602011771号