Hdu 5693 D Game【区间Dp】好题!
来源:互联网 发布:反转列表 java 编辑:程序博客网 时间:2024/05/17 04:35
D Game
Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 642 Accepted Submission(s): 232
Problem Description
众所周知,度度熊喜欢的字符只有两个:B 和D。
今天,它发明了一个游戏:D游戏。
度度熊的英文并不是很高明,所以这里的D,没什么高深的含义,只是代指等差数列[(等差数列百科)](http://baike.baidu.com/view/62268.htm)中的公差D。
这个游戏是这样的,首先度度熊拥有一个公差集合{D} ,然后它依次写下N 个数字排成一行。游戏规则很简单:
1. 在当前剩下的有序数组中选择X(X≥2) 个连续数字;
2. 检查1 选择的X 个数字是否构成等差数列,且公差 d∈{D} ;
3. 如果2 满足,可以在数组中删除这X 个数字;
4. 重复1−3 步,直到无法删除更多数字。
度度熊最多能删掉多少个数字,如果它足够聪明的话?
今天,它发明了一个游戏:D游戏。
度度熊的英文并不是很高明,所以这里的D,没什么高深的含义,只是代指等差数列[(等差数列百科)](http://baike.baidu.com/view/62268.htm)中的公差D。
这个游戏是这样的,首先度度熊拥有一个公差集合
1. 在当前剩下的有序数组中选择
2. 检查
3. 如果
4. 重复
度度熊最多能删掉多少个数字,如果它足够聪明的话?
Input
第一行一个整数T ,表示T(1≤T≤100) 组数据。
每组数据以两个整数N ,M 开始 。接着的一行包括 N 个整数,表示排成一行的有序数组 Ai 。接下来的一行是 M 个整数,即给定的公差集合 Di 。
1≤N,M≤300
−1 000 000 000≤Ai,Di≤1 000 000 000
每组数据以两个整数
Output
对于每组数据,输出最多能删掉的数字 。
Sample Input
33 11 2 313 21 2 41 24 21 3 4 31 2
Sample Output
324
Source
2016"百度之星" - 初赛(Astar Round2A)
思路:
看到数据范围.以及求最优解问题,我们优先考虑区间Dp.
那么我们不妨设定dp【i】【j】表示区间【i,j】是否能够整个删除掉。
转移看起来要从长度为2开始枚举,而且要枚举两边,时间复杂度会达到O(n^4).但是仔细想想,Gcd(2,3)=1啊。
而且长度至少要为2,那么所有其他长度都可以从2和3的组合中搞出来。
那么我们思维YY一下,就知道,我们只要转移长度为2和长度为3的小区间即可。
那么状态转移方程不是很难写出:
那么对于得到的dp数组,我们再对其状态转移一下求出最后的解即可。
Ac代码:
#include<stdio.h>#include<string.h>#include<map>using namespace std;int a[1500];int dp[350][350];int f[350];int main(){ int t; scanf("%d",&t); while(t--) { int n,m; scanf("%d%d",&n,&m); memset(dp,0,sizeof(dp)); memset(f,0,sizeof(f)); for(int i=1;i<=n;i++)scanf("%d",&a[i]); map<int ,int >s; for(int i=1;i<=m;i++) { int x;scanf("%d",&x); s[x]=1; } for(int len=1;len<=n;len++) { for(int i=1;i<=n;i++) { int j=i+len; if(j>n)break; if(len==1) { if(s[a[j]-a[i]]==1)dp[i][j]=1; continue; } if(len==2) { if(a[j]-a[j-1]==a[j-1]-a[j-2]&&s[a[j]-a[j-1]]==1) { dp[i][j]=1; } continue; } if(j<=n) { if(i+1<=j&&j-1>=i&&s[a[j]-a[i]]==1)dp[i][j]=max(dp[i][j],dp[i+1][j-1]); if(i+2<=j&&j-1>=i&&a[j]-a[i+1]==a[i+1]-a[i]&&s[a[j]-a[i+1]]==1)dp[i][j]=max(dp[i][j],dp[i+2][j-1]); if(i+1<=j&&j-2>=i&&a[j]-a[j-1]==a[j-1]-a[i]&&s[a[j]-a[j-1]]==1)dp[i][j]=max(dp[i][j],dp[i+1][j-2]); for(int k=i;k<j;k++) { if(dp[i][k]==1&&dp[k+1][j]==1)dp[i][j]=1; } } else break; } } int output=0; for(int i=1;i<=n;i++) { f[i]=0; for(int j=1;j<=i;j++) { int tmp=0; if(dp[j][i]==1)tmp=i-j+1; f[i]=max(f[i],f[j-1]+tmp); } output=max(output,f[i]); } printf("%d\n",output); }}
阅读全文
0 0
- Hdu 5693 D Game【区间Dp】好题!
- HDU 5693:D Game(区间DP)
- HDU 5693 D Game 区间dp
- HDU 5693 D Game(区间dp)
- hdu 5639 D Game 区间dp
- hdu5693(区间dp)D Game
- hdu 4597 Play Game(区间dp)
- HDU 4597 Play Game(区间dp)
- HDU 4597 - Play Game(区间DP)
- HDU-4597 Play Game (区间DP)
- hdu 4597 Play Game 区间dp
- hdu 5115 Dire Wolf【区间dp】好题
- hdu 5396 Expression(区间dp,组合数,好题)
- Hdu 2476 String painter【思维+区间Dp】好题~
- HDU 5693 D Game
- Codeforces 149D Coloring Brackets【区间Dp+思维】好题!好题!
- hdu5396Expression(区间dp,好题)
- poj3280(区间dp,好题)
- 关于Spinner默认显示的文字布局属性与下拉显示的文字布局属性如何分别设置
- 栈:中缀表达式转换成后缀表达式并求值
- OC基础-里氏替换原则12
- Corner/Voltage Regulator Pairs
- JavaScript 闭包究竟是什么JavaScript 闭包究竟是什么
- Hdu 5693 D Game【区间Dp】好题!
- jdk7 io操作小工具
- Java反射类工具获取成员的所有方法代码
- Win8 x64 + Office Word 2013 x64 无法自动加载 Endnote X6 的解决方案
- Java反射
- tensorflow中tf.random_normal和tf.truncated_normal的区别
- Struts2 Action总结
- 休息休息休息休息休息休息休息休息休息休息休息休息休息
- keras句子分类 keras_demo_for_sentence_classification (simplified version)