您的位置:首页 > 产品设计 > UI/UE

CodeChef - AMJMP Jump on Buildings 【dp + 思维】

2017-10-22 00:08 417 查看
传送门

//有一排n个高度的房子, 每次从第i个房子开始跳, 开始可以向左或者向右, 并且只能跳到比当前房子低的房子上, 并且每一次跳跃方向要和上一次相反(除了第一次). 问每个位置i可以最多跳几次.

//我们通过观察得到对于当前位置我们可以向左枚举, 然后再向右枚举, 并且记录当前这个位置到其他位置可以眺到的最远距离, dp[i][j]表示从位置i跳到位置j的最大跳跃次数是多少. 并且我们要处理的就是比当前这个数要小的的该怎么跳, 所以我们需要排序, 从小到大枚举就可以保证这一点了. 而且有一种内部关系在里面. 那么我们可以直接进行n^2枚举, 具体细节请看代码. 注意枚举跳的位置都要从当前位置向两边进行扩散, 这里好好想一想为什么!!!

AC Code

const int maxn = 5e3+5;
int cas=1;
int dp[maxn][maxn];
int a[maxn],b[maxn];
bool cmp(int x,int y)
{
return a[x] < a[y];
}
void solve()
{
int n;
while(~scanf("%d",&n)){
Fill(dp,0);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
for(int i=1;i<=n;i++) b[i] = i;
sort(b+1,b+1+n,cmp);
for(int i=1;i<=n;i++){
int x = b[i];
int mx = 0;
for(int j=x+1;j<=n;j++){
if(a[j] < a[x]) mx = max(mx,dp[x][j]);
else if(a[j] > a[x]) dp[j][x] = mx + 1;
}
mx = 0;
for(int j=x-1;j>=1;j--){
//不能从1到x-1进行枚举, 否则会越界!!! 236541
if(a[j] < a[x]) mx = max(mx,dp[x][j]);
else if(a[j] > a[x]) dp[j][x] = mx + 1;
}
}
for(int i=1;i<=n;i++){
int ans = 0;
for(int j=1;j<=n;j++){
ans = max(ans,dp[i][j]);
}
printf("%d%c",ans,i==n?'\n':' ');
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: