hdu 5693

思路:注意题目说的是删除连续的一段等差数列,2,3长度可以组成任意长度,b[i][j]表示第i个和第j个可以为等差,dp[i][j]表示i到j最长可删除等差数列

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int N=302;
 4
 5 int T;
 6 int n,m;
 7 int a[N],b[N][N],dp[N][N];
 8
 9 void hdp(){
10     for(int len=1;len<=n;len++){
11         for(int l=1;l<=n;l++){
12             int r=l+len;
13             if(r>n) break;
14             dp[l][r]=max(dp[l+1][r],dp[l][r-1]);
15             if(b[l][r]&&dp[l+1][r-1]==(r-l-1))
16                 dp[l][r]=max(dp[l][r],dp[l+1][r-1]+2);
17             for(int i=l+1;i<r;i++)
18                 dp[l][r]=max(dp[l][r],dp[l][i]+dp[i+1][r]);
19             for(int i=l+1;i<=r;i++){
20                 if(b[l][i]&&dp[l+1][i-1]==(i-l-1))
21                     dp[l][r]=max(dp[l][r],dp[l+1][i-1]+2);
22                 if(b[i][r]&&dp[i+1][r-1]==(r-i-1))
23                      dp[l][r]=max(dp[l][r],dp[i+1][r-1]+2);
24                 if(b[l][i]&&b[i][r]&&a[i]-a[l]==a[r]-a[i]&&dp[l+1][i-1]==(i-l-1)&&dp[i+1][r-1]==(r-i-1)){
25                     dp[l][r]=max(dp[l][r],r-l+1);
26                 }
27             }
28         }
29     }
30 }
31
32 void slove(){
33     int x;
34     memset(dp,0,sizeof(dp));
35     memset(b,0,sizeof(b));
36     scanf("%d%d",&n,&m);
37     for(int i=1;i<=n;i++) scanf("%d",&a[i]);
38     for(int i=1;i<=m;i++){
39         scanf("%d",&x);
40         for(int j=1;j<=n;j++){
41             for(int k=j+1;k<=n;k++){
42                 if(a[k]-a[j]==x) b[j][k]=1;
43             }
44         }
45     }
46     hdp();
47     printf("%d\n",dp[1][n]);
48 }
49 int main(){
50     scanf("%d",&T);
51     while(T--){
52         slove();
53     }
54 }
时间: 2024-11-02 23:24:05

hdu 5693的相关文章

hdu 5693 &amp;&amp; LightOj 1422 区间DP

hdu 5693 题目链接http://acm.hdu.edu.cn/showproblem.php?pid=5693 等差数列当划分细了后只用比较2个或者3个数就可以了,因为大于3的数都可以由2和3组合成. 区间DP,用dp[i][j]表示在i到j之间可以删除的最大数,枚举区间长度,再考虑区间两端是否满足等差数列(这是考虑两个数的),再i到j之间枚举k,分别判断左端点右端点和k是否构成等差数列(还是考虑两个数的),判断左端点,k,右端点是否构成等差数列(这是老驴三个数的) 1 #include

hdu 5693 D Game

D Game HDU - 5693 众所周知,度度熊喜欢的字符只有两个:B 和D. 今天,它发明了一个游戏:D游戏. 度度熊的英文并不是很高明,所以这里的D,没什么高深的含义,只是代指等差数列[(等差数列百科)](http://baike.baidu.com/view/62268.htm)中的公差D. 这个游戏是这样的,首先度度熊拥有一个公差集合$\{D\}$,然后它依次写下$N$个数字排成一行.游戏规则很简单: 1. 在当前剩下的有序数组中选择$X (X \geq 2)$ 个连续数字: 2.

HDU 5693 D Game 递归暴力

http://blog.csdn.net/angon823/article/details/51484906 #include <cstdio> #include <iostream> #include <algorithm> #include <cstring> #include <cmath> using namespace std; typedef long long LL; LL solve(LL x){ if(x<=0)retur

hdu 5693 朋友 博弈

朋友 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Problem Description B君在围观一群男生和一群女生玩游戏,具体来说游戏是这样的:给出一棵n个节点的树,这棵树的每条边有一个权值,这个权值只可能是0或1. 在一局游戏开始时,会确定一个节点作为根.接下来从女生开始,双方轮流进行 操作.当一方操作时,他们需要先选择一个不为根的点,满足该点到其父亲的边权为1; 然

QBXT 2018春季DP&amp;图论班 2018.5.3 --- 区间DP专题

本文题目等来自北京大学张浩威学长的PPT. 1.区间DP:解决有关两个或以上的区间的合并或删除的问题(最大/小次数/价值.方案总数.可行性等). 2.石子合并: 有n堆石子排成一排,第i堆石子的个数为ai.每次可以将相邻两堆合并成一堆.合并的代价为两堆石子的石子个数之和.设计方案要求代价之和最小. 状态:dp[l][r]表示只考虑区间l~r的石子,将它们合并的最小代价. 状态转移:dp[l][r]=min{dp[l][r],dp[l][k]+dp[k+1][r]+s[r]-s[l-1]} l~r

HDU 6203 ping ping ping [LCA,贪心,DFS序,BIT(树状数组)]

题目链接:[http://acm.hdu.edu.cn/showproblem.php?pid=6203] 题意 :给出一棵树,如果(a,b)路径上有坏点,那么(a,b)之间不联通,给出一些不联通的点对,然后判断最少有多少个坏点. 题解 :求每个点对的LCA,然后根据LCA的深度排序.从LCA最深的点对开始,如果a或者b点已经有点被标记了,那么continue,否者标记(a,b)LCA的子树每个顶点加1. #include<Bits/stdc++.h> using namespace std;

HDU 5542 The Battle of Chibi dp+树状数组

题目:http://acm.hdu.edu.cn/showproblem.php?pid=5542 题意:给你n个数,求其中上升子序列长度为m的个数 可以考虑用dp[i][j]表示以a[i]结尾的长度为j的上升子序列有多少 裸的dp是o(n2m) 所以需要优化 我们可以发现dp的第3维是找比它小的数,那么就可以用树状数组来找 这样就可以降低复杂度 #include<iostream> #include<cstdio> #include<cstring> #include

hdu 1207 汉诺塔II (DP+递推)

汉诺塔II Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 4529    Accepted Submission(s): 2231 Problem Description 经典的汉诺塔问题经常作为一个递归的经典例题存在.可能有人并不知道汉诺塔问题的典故.汉诺塔来源于印度传说的一个故事,上帝创造世界时作了三根金刚石柱子,在一根柱子上从下往

[hdu 2102]bfs+注意INF

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2102 感觉这个题非常水,结果一直WA,最后发现居然是0x3f3f3f3f不够大导致的--把INF改成INF+INF就过了. #include<bits/stdc++.h> using namespace std; bool vis[2][15][15]; char s[2][15][15]; const int INF=0x3f3f3f3f; const int fx[]={0,0,1,-1};