Codeforces 505C Mr. Kitayuta, the Treasure Hunter DP+技巧优化
2017-04-19 15:59
337 查看
点击打开链接
题意:数轴上点[0, 30000]。先从 0 跳到 d<=3e4 以后每次跳的步数是 {prev-1, prev, prev+1}。跳得步数必须>=1,跳到某个点上可以得到相应的value,求可以得到最大的value。
明显DP阿,设dp[i][j] 当前在i,上一次跳跃距离为j,dp[i][j]=max(dp[i+j][j],dp[i+j+1][j+1],dp[i+j-1][j-1])+val[i];
i,j<=3e4 爆空间了,直觉:每次所在点都是递增的,没有那么多状态 用map水一发,结果TLE (卡STL了,差一点)
考虑最坏的情况 起点为0,任意给d d每次+1 最大可以变化到 d+k 则 (k+1)(d+d+k)/2<=3e4 k<=sqrt(2*M) 最小变化也是一样
则d 最多变化sqrt(M)次 状态最多也只有O(Msqrt(M)个 每次转移O(1),把d映射成sqrt(M) 记忆化DP即可
#include <bits/stdc++.h>
using namespace std;
const int N=3e4+20;
const int M=3e4;
int n,d,mx,ans,cnt=0,b;
int val
,p
;
int dp
[1200];//dp[i][j] 当前在i上一次跳跃距离为j
//j的转移不会超过sqrt(M),j映射sqrt(M)
int DP(int i,int j,int k)//j->k
{
if(dp[i][k]!=-1)
return dp[i][k];
dp[i][k]=val[i];
int res=0;
if(i+j<=mx)
res=max(res,DP(i+j,j,k));
if(i+j+1<=mx)
res=max(res,DP(i+j+1,j+1,k+1));
if(i+j-1<=mx&&j-1>=1)
res=max(res,DP(i+j-1,j-1,k-1));
dp[i][k]+=res;
return dp[i][k];
}
int main()
{
while(cin>>n>>d)
{
memset(p,0,sizeof(p));
mx=ans=0;
int x;
memset(dp,-1,sizeof(dp));
memset(val,0,sizeof(val));
for(int i=0;i<n;i++)
scanf("%d",&x),val[x]++,mx=max(mx,x);
b=2*(int)sqrt(M);
ans=DP(d,d,b);
printf("%d\n",ans);
}
return 0;
}
题意:数轴上点[0, 30000]。先从 0 跳到 d<=3e4 以后每次跳的步数是 {prev-1, prev, prev+1}。跳得步数必须>=1,跳到某个点上可以得到相应的value,求可以得到最大的value。
明显DP阿,设dp[i][j] 当前在i,上一次跳跃距离为j,dp[i][j]=max(dp[i+j][j],dp[i+j+1][j+1],dp[i+j-1][j-1])+val[i];
i,j<=3e4 爆空间了,直觉:每次所在点都是递增的,没有那么多状态 用map水一发,结果TLE (卡STL了,差一点)
考虑最坏的情况 起点为0,任意给d d每次+1 最大可以变化到 d+k 则 (k+1)(d+d+k)/2<=3e4 k<=sqrt(2*M) 最小变化也是一样
则d 最多变化sqrt(M)次 状态最多也只有O(Msqrt(M)个 每次转移O(1),把d映射成sqrt(M) 记忆化DP即可
#include <bits/stdc++.h>
using namespace std;
const int N=3e4+20;
const int M=3e4;
int n,d,mx,ans,cnt=0,b;
int val
,p
;
int dp
[1200];//dp[i][j] 当前在i上一次跳跃距离为j
//j的转移不会超过sqrt(M),j映射sqrt(M)
int DP(int i,int j,int k)//j->k
{
if(dp[i][k]!=-1)
return dp[i][k];
dp[i][k]=val[i];
int res=0;
if(i+j<=mx)
res=max(res,DP(i+j,j,k));
if(i+j+1<=mx)
res=max(res,DP(i+j+1,j+1,k+1));
if(i+j-1<=mx&&j-1>=1)
res=max(res,DP(i+j-1,j-1,k-1));
dp[i][k]+=res;
return dp[i][k];
}
int main()
{
while(cin>>n>>d)
{
memset(p,0,sizeof(p));
mx=ans=0;
int x;
memset(dp,-1,sizeof(dp));
memset(val,0,sizeof(val));
for(int i=0;i<n;i++)
scanf("%d",&x),val[x]++,mx=max(mx,x);
b=2*(int)sqrt(M);
ans=DP(d,d,b);
printf("%d\n",ans);
}
return 0;
}
相关文章推荐
- codeforces 505C C. Mr. Kitayuta, the Treasure Hunter (dp)
- 【codeforces 505C】Mr.Kitayuta,the Treasure Hunter
- codeforces 505C C. Mr. Kitayuta, the Treasure Hunter(dp)
- CF 505C(Mr. Kitayuta, the Treasure Hunter-Dp考虑可用范围)
- [Codeforces 505C]Mr. Kitayuta, the Treasure Hunter
- CF 286DIV2 C. Mr. Kitayuta, the Treasure Hunter(dp)
- Codeforces Round #286 (Div. 2) C题 Mr. Kitayuta, the Treasure Hunter (DFS+记忆化DP)
- CF - 286 - div2 - C - Mr. Kitayuta, the Treasure Hunter (DP)
- Codeforces Round #286 Div.1 A Mr. Kitayuta, the Treasure Hunter --DP
- Codeforces Round #286 (Div. 2) C. Mr. Kitayuta, the Treasure Hunter——dp
- Codeforces Round #286 (Div. 2) C Mr. Kitayuta, the Treasure Hunter ( DP )
- Codeforces Round #286 (Div. 2) C. Mr. Kitayuta, the Treasure Hunter dp+范围压缩
- 【DP】 Codeforces Round #286 A - Mr. Kitayuta, the Treasure Hunter
- 【CodeForces506A】【DP】【记忆化搜索】Mr. Kitayuta, the Treasure Hunter 题解
- CodeForces 506 Div.1 A. Mr. Kitayuta, the Treasure Hunter
- Codeforces Round #286 (Div. 2) C. Mr. Kitayuta, the Treasure Hunter dp
- CF505C——Mr. Kitayuta, the Treasure Hunter(DP)
- cf#186-C. Mr. Kitayuta, the Treasure Hunter-dp(预推断+offset)
- dp cf C. Mr. Kitayuta, the Treasure Hunter
- [Codeforces Round #286 DIV1A (CF506A)] Mr. Kitayuta, the Treasure Hunter