250pt:
1234+ 12340+ 123400+ 1234000+ 12340000+ 123400000+ 1234000000------------ 1371110974 |
一個數的magic source是最小的一個正整數x,滿足sigma(x*10^i) [i=0~n] = 這個數。
如上,1234被稱為是1371110974的magic source, 其實就是x*(1111111) = 這個數,求最小的x就是求最大的1111。。。111。
500pt:
給你網格中的50個點,網格的範圍是10000大小,問你一個人從(0,0)出發最多能經過幾個點,走的條件是:每次y方向只能位移一個單位,x方向能位移k,但是必須嚴格大於上一次的位移量kp,也就是說x方向上的跨度越來越大 ,y方向上的跨度不變。
這種被各路英雄秒殺的題我能想半天。。。。
其實關鍵是x這個座標不好處理,但是只要注意到兩個特性就能輕鬆的AC此題。
1:這個人走的路線是基於這些點的,跟其他的座標點沒關係
2:在同一個點時,步長越短,對以後的選擇空間就越大,相對於其他狀態相同的但是步長比他長的狀態S來說,S能走到的點,這個狀態一定能走到,但是步長短的點能走到的點,S狀態的人就不一定能走到了,所以狀態就出來了。。。
int dp[55][55] ;struct node { int x,y; bool operator < (const node& cmp) const { return y < cmp.y ; }}in[55];void Min(int &x,int y){ if(x == -1 || y < x) x = y;}int BaronsAndCoins::getMaximum(vector<int> x, vector<int> y){ memset(dp,-1,sizeof(dp)); dp[0][0] = 0; int n = x.size(); in[0].x = 0; in[0].y = 0; for(int i = 1; i <= n; i++) { in[i].x = x[i-1]; in[i].y = y[i-1]; } sort(in+1,in+n+1); for(int i = 0; i < n; i++) { for(int j = 0; j < n; j++) if(dp[i][j] != -1) { for(int k = i+1; k <= n; k++) if(in[k].x > in[i].x &&in[k].y > in[i].y) { int step = dp[i][j]; int delta_col = in[k].y - in[i].y; int delta_row = in[k].x - in[i].x; int val = (step+1+step+delta_col)*delta_col/2; if(val > delta_row) continue; int extra = (delta_row - val) / delta_col; if((delta_row-val) % delta_col != 0)extra ++; Min(dp[k][j+1],step+delta_col+extra); } } } int ans = 0; for(int i = 0; i <= n; i++) { for(int j = 0; j <= n; j++) { if(dp[i][j] != -1) ans = max(ans,j); } } return ans;}