题目链接:5693

题目链接:5712

对于这个D game。注意消除之后两遍的序列是可以拼合到一起的!我们可以想到有区间DP的做法。我们设\(f[i][j]\)表示区间i,j可以被消除。

显然如果这个区间可以被消除,则操作一定可以被分解成一次消除两个k1次,一次消除三个k2次。所以我们只考虑消除两个和消除三个的情况即可。

开始可以把公差放进set里面,方便之后查询。

具体转移见代码。

处理完哪些区间可以被消除之后,我们可以利用贪心来计算最大消除的数量。(要先把可行区间放入到一个vector里面,然后排序,按照长度为第一关键字,左端点为第二关键字。因为大区间一定覆盖它里面的小区间,所以我们只要遇到自己区间已经被计算过了就不用计算这整个区间了)。

代码如下:

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<set>
#include<vector>
#define MAXN 310
using namespace std;
int t,n,m,cur,ans;
struct Edge{int l,r,dis;};
int a[MAXN],f[MAXN][MAXN],done[MAXN],dp[MAXN];
set<int>s;
vector<Edge>v;
inline bool cmp(struct Edge x,struct Edge y)
{
if(x.dis==y.dis) return x.l<y.l;
return x.dis>y.dis;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("ce.in","r",stdin);
#endif
scanf("%d",&t);
while(t--)
{
ans=0;
s.clear();v.clear();
memset(f,0,sizeof(f));
memset(done,0,sizeof(done));
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%d",&a[i]),f[i][i-1]=1;
for(int i=1;i<=m;i++) scanf("%d",&cur),s.insert(cur);
for(int i=1;i<=n;i++)
{
for(int l=1;l+i<=n;l++)
{
int r=l+i;
//printf("l=%d r=%d\n",l,r);
if(f[l+1][r-1]&&s.count(a[r]-a[l])) f[l][r]=1;
if(!f[l][r])
{
for(int k=l+1;k<=r-1;k++)
{
int cha1=a[r]-a[k],cha2=a[k]-a[l];
if((f[l][k-1]&&f[k][r])||(f[l+1][k-1]&&f[k+1][r-1]&&cha1==cha2&&s.count(cha1)))
{f[l][r]=1;break;}
}
}
}
}
for(int i=1;i<=n-1;i++)
for(int j=i+1;j<=n;j++)
if(f[i][j])
v.push_back((Edge){i,j,j-i+1});
sort(v.begin(),v.end(),cmp);
int cur=0;
for(int i=0;i<v.size();i++)
{
bool flag=true;
for(int j=v[i].l;j<=v[i].r;j++)
if(done[j]==1)
{flag=false;break;}
if(flag==false) continue;
for(int j=v[i].l;j<=v[i].r;j++)
done[j]=1;
}
for(int i=1;i<=n;i++) if(done[i]) ans++;
printf("%d\n",ans);
}
return 0;
}

然后对于那个加强版。

我想的是因为它的公差的种类数量很少,所以我想的是直接记录一下哪个区间里面有多少种公差,那么就知道了消除这个区间至少需要多少次。但是这样的话没有办法判断一次消除到底有没有满足消除数量在min,max范围内。。。。

所以说这个题我还木有A掉。。。。但是在网上也没有找到题解。。。。就先把自己WA的代码放在这里好了。。。

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<set>
#include<vector>
#include<map>
#define MAXN 100
using namespace std;
int t,n,m,cur,ans,minn,maxx,cnt,kkk;
struct Edge{int l,r,dis;};
struct Node{int sum[40];}node[MAXN][MAXN];
int a[MAXN],f[MAXN][MAXN],done[MAXN],dp[MAXN];
set<int>s;
vector<Edge>v;
map<int,int>id;
inline bool cmp(struct Edge x,struct Edge y)
{
if(x.dis==y.dis) return x.l<y.l;
return x.dis>y.dis;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("ce.in","r",stdin);
#endif
scanf("%d",&t);
while(t--)
{
kkk++;
ans=cnt=0;
s.clear();v.clear();
memset(f,0,sizeof(f));
memset(done,0,sizeof(done));
scanf("%d%d%d%d",&n,&m,&minn,&maxx);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
for(int i=1;i<=m;i++) scanf("%d",&cur),s.insert(cur),id[cur]=i;
for(int i=1;i<=n;i++)
{
f[i][i-1]=1;
if(s.count(a[i+1]-a[i]))
node[i][i-1].sum[id[a[i+1]-a[i]]]=1;
}
for(int i=1;i<=n;i++)
{
for(int l=1;l+i<=n;l++)
{
int r=l+i;
if(f[l+1][r-1]&&s.count(a[r]-a[l])&&a[r]!=a[r-1]&&a[l]!=a[l+1])
{
f[l][r]=1;
for(int k=1;k<=32;k++) node[l][r].sum[k]=node[l+1][r-1].sum[k];
node[l][r].sum[id[a[r]-a[l]]]=1;
}
vector<int>put,cur_ans;
if(!f[l][r])
{
for(int k=l+1;k<=r-1;k++)
{
int cha1=a[r]-a[k],cha2=a[k]-a[l];
if(f[l][k-1]&&f[k][r]&&a[k]!=a[k-1])
{
f[l][r]=1;
put.clear();
for(int p=1;p<=32;p++)
if(node[l][k-1].sum[p]||node[k][r].sum[p])
put.push_back(p);
if(cur_ans.size()==0)
for(int q=0;q<put.size();q++)
cur_ans.push_back(put[q]);
if(cur_ans.size()!=0&&put.size()<cur_ans.size())
{
cur_ans.clear();
for(int q=0;q<put.size();q++)
cur_ans.push_back(put[q]);
}
}
if(f[l+1][k-1]&&f[k+1][r-1]&&cha1==cha2&&s.count(cha1))
{
if(a[l]==a[l+1]||a[k-1]==a[k]||a[k]==a[k+1]||a[r-1]==a[r]) continue;
f[l][r]=1;
put.clear();
for(int p=1;p<=32;p++)
if(node[l+1][k-1].sum[p]||node[k+1][r-1].sum[p]||p==id[cha1])
put.push_back(p);
if(cur_ans.size()==0)
for(int q=0;q<put.size();q++)
cur_ans.push_back(put[q]);
if(cur_ans.size()!=0&&put.size()<cur_ans.size())
{
cur_ans.clear();
for(int q=0;q<put.size();q++)
cur_ans.push_back(put[q]);
}
}
}
}
if(f[l][r])
for(int k=0;k<cur_ans.size();k++)
node[l][r].sum[cur_ans[k]]=1;
}
}
for(int i=1;i<=n-1;i++)
for(int j=i+1;j<=n;j++)
if(f[i][j])
v.push_back((Edge){i,j,j-i+1});
sort(v.begin(),v.end(),cmp);
int cnt=0;
for(int i=0;i<v.size();i++)
{
if(v[i].dis<minn) continue;
//int k1=v[i].dis/minn;
//if((maxx-minn)*k<v[i].dis-k*minn) continue;
int k=v[i].dis/maxx+(v[i].dis%maxx==0?0:1);
if((v[i].dis%maxx!=0)&&(v[i].dis%maxx+(k-1)*(maxx-minn)<minn)) continue;
bool flag=true;
for(int j=v[i].l;j<=v[i].r;j++)
if(done[j]==1)
{flag=false;break;}
if(flag==false) continue;
for(int j=v[i].l;j<=v[i].r;j++)
done[j]=1;
for(int j=1;j<=32;j++)
if(node[v[i].l][v[i].r].sum[j])
cnt++;
}
for(int i=1;i<=n;i++) if(done[i]) ans++;
printf("Case #%d:\n%d %d\n",kkk,ans,cnt);
}
return 0;
}

hdu5693 D game&&hdu 5712 D++ game的更多相关文章

  1. HDOJ 2111. Saving HDU 贪心 结构体排序

    Saving HDU Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total ...

  2. 【HDU 3037】Saving Beans Lucas定理模板

    http://acm.hdu.edu.cn/showproblem.php?pid=3037 Lucas定理模板. 现在才写,noip滚粗前兆QAQ #include<cstdio> #i ...

  3. hdu 4859 海岸线 Bestcoder Round 1

    http://acm.hdu.edu.cn/showproblem.php?pid=4859 题目大意: 在一个矩形周围都是海,这个矩形中有陆地,深海和浅海.浅海是可以填成陆地的. 求最多有多少条方格 ...

  4. HDU 4569 Special equations(取模)

    Special equations Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u S ...

  5. HDU 4006The kth great number(K大数 +小顶堆)

    The kth great number Time Limit:1000MS     Memory Limit:65768KB     64bit IO Format:%I64d & %I64 ...

  6. HDU 1796How many integers can you find(容斥原理)

    How many integers can you find Time Limit:5000MS     Memory Limit:32768KB     64bit IO Format:%I64d ...

  7. hdu 4481 Time travel(高斯求期望)(转)

    (转)http://blog.csdn.net/u013081425/article/details/39240021 http://acm.hdu.edu.cn/showproblem.php?pi ...

  8. HDU 3791二叉搜索树解题(解题报告)

    1.题目地址: http://acm.hdu.edu.cn/showproblem.php?pid=3791 2.参考解题 http://blog.csdn.net/u013447865/articl ...

  9. hdu 4329

    problem:http://acm.hdu.edu.cn/showproblem.php?pid=4329 题意:模拟  a.     p(r)=   R'/i   rel(r)=(1||0)  R ...

随机推荐

  1. margin+absolute布局:右栏固定主内容自适应 demo

    margin+absolute布局:右栏固定主内容自适应 demo 头部 Aside侧边栏区域 Main主内容区域 底部 #demo{width:80%;margin:auto;height:300p ...

  2. bash's parameter expansion

    [bash's parameter expansion] #: find first from left, remove-left ##: find last from left, remove le ...

  3. 【BZOJ2038】小Z的袜子【莫队】

    题意 给出包含n个数字的序列,和m个查询.每次查询问区间[l,r]中挑选出两个数字,大小相同的概率为多少. 分析 莫队的入门题吧.代码是非常好写,关键是时间复杂度的证明.O(n*sqrt(n)).我还 ...

  4. [erlang 001] erlang中的错误及异常处理

    一. erlang中的错误 1. 分类 1) 编译错误:主要是编译器检测出的代码语法错误: 2) 逻辑错误:是指程序没有完成预期的工作,属于开发人员的问题: 3) 运行时错误:是指erlang运行时抛 ...

  5. ROS Learning-032 (提高篇-010 Launch)Launch 深入研究 --- (启动文件编程)ROS 的 XML语法简介

    ROS 提高篇 之 Launch 深入研究 - 01 - 启动文件的编程 - ROS 的 XML语法简介 我使用的虚拟机软件:VMware Workstation 11 使用的Ubuntu系统:Ubu ...

  6. 关于select Count()的使用和性能问题

    比如Count(*) FROM E_Table WHERE [date] > '2008-1-1' AND istrue = 0 由于操作的数据比较大(400万以上),所以使用了两个数据库,一个 ...

  7. Win 7 Windows Update无法自动更新解决方案

    最近发现系统很长时间没有自动更新过了,手动更新后,提示返回错误码WindowsUpdate_8024402F.网络上搜索到的解决方法大多是删除更新临时目录,重启WINDOWS UPDATE服务,然而试 ...

  8. Spring Data JPA初使用 *****重要********

    Spring Data JPA初使用 我们都知道Spring是一个非常优秀的JavaEE整合框架,它尽可能的减少我们开发的工作量和难度. 在持久层的业务逻辑方面,Spring开源组织又给我们带来了同样 ...

  9. 实践作业3:白盒测试----junit的难点DAY11.

    本次白盒测试 需要独立完成整个项目和工具的配置安装运行操作,并编写.运行测试脚本,并完成实验的一些小细节等等. 首先,导入Junit测试框架所需的Jar包 然后编写测试脚本,为.java运行程序,见打 ...

  10. myisam innodb memory 区别(2)

    1.区别:1) MyISAM管理非事务表.提供高速存储和检索,以及全文搜索能力.MyISAM在所有MySQL配置里被支持,是默认的存储引擎,除非配置MySQL默认使用另外一个引擎.2)MEMORY存储 ...