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;
}