codeforces 505C Mr. Kitayuta, the Treasure Hunter(dp)
2015-01-19 22:05
411 查看
题目链接
C. Mr. Kitayuta, the Treasure Hunter
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output
The Shuseki Islands are an archipelago of 30001 small islands in the Yutampo Sea. The islands are evenly spaced along a line, numbered from 0 to 30000 from
the west to the east. These islands are known to contain many treasures. There are n gems in the Shuseki Islands in total, and the i-th
gem is located on island pi.
Mr. Kitayuta has just arrived at island 0. With his great jumping ability, he will repeatedly perform jumps between islands to the east according to the following
process:
First, he will jump from island 0 to island d.
After that, he will continue jumping according to the following rule. Let l be the length of the previous jump, that is, if his previous jump was from island prev to
island cur, let l = cur - prev.
He will perform a jump of length l - 1, l or l + 1 to
the east. That is, he will jump to island (cur + l - 1), (cur + l) or (cur + l + 1) (if
they exist). The length of a jump must be positive, that is, he cannot perform a jump of length 0 when l = 1.
If there is no valid destination, he will stop jumping.
Mr. Kitayuta will collect the gems on the islands visited during the process. Find the maximum number of gems that he can collect.
Input
The first line of the input contains two space-separated integers n and d (1 ≤ n, d ≤ 30000),
denoting the number of the gems in the Shuseki Islands and the length of the Mr. Kitayuta's first jump, respectively.
The next n lines describe the location of the gems. The i-th
of them (1 ≤ i ≤ n) contains a integer pi (d ≤ p1 ≤ p2 ≤ ... ≤ pn ≤ 30000),
denoting the number of the island that contains the i-th gem.
Output
Print the maximum number of gems that Mr. Kitayuta can collect.
Sample test(s)
input
output
input
output
input
output
题意:有30001个岛,在一条线上,从左到右编号一次为0到30000。某些岛屿上有些宝石。初始的时候有个人在岛屿0,他将跳到岛屿d,他跳跃的距离为d。如果当前他跳跃的距离为L,他下一次跳跃的距离只能为L-1,L,L+1之一且不能为0。他只能往编号更大的岛跳,直到他不能跳,问他最多能收集多少个宝石?
题解:很容易想到dp,用dp[i][j] 表示当前在岛屿i,上一次跳跃的距离为j,最多能收集多少个宝石。但是这样无论空间还是时间都不能接受。我们可以发现,他跳跃的距离L不会超过d+250,因为1+2+3+...250>30000。有了这个性质,我们就可以用dp[i][j]表示当前在岛屿i,上一次跳跃的距离为d+j,该状态下他最多能收集多少个宝石?
空间复杂度和时间复杂度都为O(n*sqrt(n))。
代码如下:
复杂度为O(10^7),代码如下:
C. Mr. Kitayuta, the Treasure Hunter
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output
The Shuseki Islands are an archipelago of 30001 small islands in the Yutampo Sea. The islands are evenly spaced along a line, numbered from 0 to 30000 from
the west to the east. These islands are known to contain many treasures. There are n gems in the Shuseki Islands in total, and the i-th
gem is located on island pi.
Mr. Kitayuta has just arrived at island 0. With his great jumping ability, he will repeatedly perform jumps between islands to the east according to the following
process:
First, he will jump from island 0 to island d.
After that, he will continue jumping according to the following rule. Let l be the length of the previous jump, that is, if his previous jump was from island prev to
island cur, let l = cur - prev.
He will perform a jump of length l - 1, l or l + 1 to
the east. That is, he will jump to island (cur + l - 1), (cur + l) or (cur + l + 1) (if
they exist). The length of a jump must be positive, that is, he cannot perform a jump of length 0 when l = 1.
If there is no valid destination, he will stop jumping.
Mr. Kitayuta will collect the gems on the islands visited during the process. Find the maximum number of gems that he can collect.
Input
The first line of the input contains two space-separated integers n and d (1 ≤ n, d ≤ 30000),
denoting the number of the gems in the Shuseki Islands and the length of the Mr. Kitayuta's first jump, respectively.
The next n lines describe the location of the gems. The i-th
of them (1 ≤ i ≤ n) contains a integer pi (d ≤ p1 ≤ p2 ≤ ... ≤ pn ≤ 30000),
denoting the number of the island that contains the i-th gem.
Output
Print the maximum number of gems that Mr. Kitayuta can collect.
Sample test(s)
input
4 10 10 21 27 27
output
3
input
8 8 9 19 28 36 45 55 66 78
output
6
input
13 7
8
8
9
1617
17
18
21
2324
24
2630
output
4
题意:有30001个岛,在一条线上,从左到右编号一次为0到30000。某些岛屿上有些宝石。初始的时候有个人在岛屿0,他将跳到岛屿d,他跳跃的距离为d。如果当前他跳跃的距离为L,他下一次跳跃的距离只能为L-1,L,L+1之一且不能为0。他只能往编号更大的岛跳,直到他不能跳,问他最多能收集多少个宝石?
题解:很容易想到dp,用dp[i][j] 表示当前在岛屿i,上一次跳跃的距离为j,最多能收集多少个宝石。但是这样无论空间还是时间都不能接受。我们可以发现,他跳跃的距离L不会超过d+250,因为1+2+3+...250>30000。有了这个性质,我们就可以用dp[i][j]表示当前在岛屿i,上一次跳跃的距离为d+j,该状态下他最多能收集多少个宝石?
空间复杂度和时间复杂度都为O(n*sqrt(n))。
代码如下:
#include<stdio.h> #include<iostream> #include<algorithm> #include<string.h> #include<string> #include<queue> #include<stack> #include<map> #include<set> #include<stdlib.h> #include<vector> #define inff 0x3fffffff #define nn 110000 #define mod 1000000007 typedef long long LL; const LL inf64=inff*(LL)inff; using namespace std; int n,d; int num[31000]; int dp[31000][510]; int main() { int i,x,j; while(scanf("%d%d",&n,&d)!=EOF) { memset(num,0,sizeof(num)); for(i=1;i<=n;i++) { scanf("%d",&x); num[x]++; } memset(dp,-1,sizeof(dp)); dp[d][250]=num[d]; int ans=0; for(i=d;i<=30000;i++) { for(j=0;j<=500;j++) { if(dp[i][j]!=-1) { ans=max(dp[i][j],ans); if(i+d+j-250<=30000) dp[i+d+j-250][j]=max(dp[i+d+j-250][j],dp[i][j]+num[i+d+j-250]); if(i+d+j-1-250<=30000&&d+j-250-1) dp[i+d+j-251][j-1]=max(dp[i+d+j-251][j-1],dp[i][j]+num[i+d+j-251]); if(i+d+j+1-250<=30000) dp[i+d+j+1-250][j+1]=max(dp[i+d+j+1-250][j+1],dp[i][j]+num[i+d+j+1-250]); } } } printf("%d\n",ans); } return 0; }比赛的时候我没有想到正解,但是知道有效状态数不会太多,所以使用记忆化搜索写过的,当然还要到hash。
复杂度为O(10^7),代码如下:
#include<stdio.h> #include<iostream> #include<algorithm> #include<string.h> #include<string> #include<queue> #include<stack> #include<map> #include<set> #include<stdlib.h> #include<vector> #define inff 0x3fffffff #define nn 21000 #define mod 20000009 typedef long long LL; const LL inf64=inff*(LL)inff; using namespace std; int n,d; int num[3*nn]; int sum[3*nn]; int mxid; int ha[nn*1000]; int hashx(int x,int y) { int ix=x+30007*y; int key=ix%mod; int i; for(i=key;;i=(i+1)%mod) { if(ha[i]==-1) { ha[i]=ix; break; } else if(ha[i]==ix) break; } return i; } int dp[nn*1000]; int dfs(int id,int l) { if(l==1||l==2) return sum[mxid]-sum[id-1]; int ix=hashx(id,l); if(dp[ix]!=-1) return dp[ix]; int re=0; if(id+l<=mxid) re=max(re,dfs(id+l,l)); if(id+l-1<=mxid&&l-1>0) re=max(re,dfs(id+l-1,l-1)); if(id+l+1<=mxid) re=max(re,dfs(id+l+1,l+1)); return dp[ix]=re+num[id]; } int main() { int i,x; while(scanf("%d%d",&n,&d)!=EOF) { memset(num,0,sizeof(num)); memset(ha,-1,sizeof(ha)); memset(dp,-1,sizeof(dp)); sum[0]=0; for(i=1;i<=n;i++) { scanf("%d",&x); num[x]++; mxid=x; } for(i=1;i<=mxid;i++) { sum[i]=sum[i-1]+num[i]; } if(d==1||d==2) printf("%d\n",n); else printf("%d\n",dfs(d,d)); } return 0; }
相关文章推荐
- codeforces 505C Mr. Kitayuta, the Treasure Hunter( dp 缩减规模 )
- codeforces 505C Mr. Kitayuta, the Treasure Hunter(dp)
- codeforces 505C C. Mr. Kitayuta, the Treasure Hunter(dp)
- codeforces 505C C. Mr. Kitayuta, the Treasure Hunter (dp)
- codeforces 505C Mr. Kitayuta, the Treasure Hunter(DP)
- Codeforces 505C Mr. Kitayuta, the Treasure Hunter DP+技巧优化
- CodeForces 505C Mr. Kitayuta, the Treasure Hunter
- Codeforces 505C Mr. Kitayuta, the Treasure Hunter【记忆化搜索+分块数据处理】好题
- dp cf C. Mr. Kitayuta, the Treasure Hunter
- codeforces 505C. Mr. Kitayuta, the Treasure Hunter (记忆化搜索)
- CF 286DIV2 C. Mr. Kitayuta, the Treasure Hunter(dp)
- cf#186-C. Mr. Kitayuta, the Treasure Hunter-dp(预推断+offset)
- CF 505C(Mr. Kitayuta, the Treasure Hunter-Dp考虑可用范围)
- Codeforces Round #286 (Div. 2) C题 Mr. Kitayuta, the Treasure Hunter (DFS+记忆化DP)
- Codeforces Round #286 (Div. 2) C Mr. Kitayuta, the Treasure Hunter ( DP )
- CF505C——Mr. Kitayuta, the Treasure Hunter(DP)
- CF - 286 - div2 - C - Mr. Kitayuta, the Treasure Hunter (DP)
- CodeForces-505C Mr. Kitayuta, the Treasure Hunter
- CodeForces #505C# Mr. Kitayuta, the Treasure Hunter(dp数组定义)
- Codeforces Round #286 (Div. 2) C. Mr. Kitayuta, the Treasure Hunter dp