【BZOJ4927】第一题

Description

给定n根直的木棍,要从中选出6根木棍,满足:能用这6根木棍拼
出一个正方形。注意木棍不能弯折。问方案数。
正方形:四条边都相等、四个角都是直角的四边形。

Input

第一行一个整数n。
第二行包含n个整数ai,代表每根木棍的长度。
n ≤ 5000, 1 ≤ ai ≤ 10^7

Output

一行一个整数,代表方案数。

Sample Input

8
4 5 1 5 1 9 4 5

Sample Output

3

题解:这。。。这不是沈阳集训的原题吗?(xqz说是山东集训的原题)

由于题目让你拼的是正方形,那么这个正方形的组成显然只有两种情况:3+1+1+1或2+2+1+1(这里指的是正方形的四条边),那么我们分类讨论这两种情况。

如果是2+2+1+1,那么我们可以枚举最长的那2根木棍(也就是两个1的长度)。显然要先排序,并将长度相同的木棍合在一起。然后我们已知正方形的边长,那么问题就变成了如何选出4根木棍a,b,c,d使得a+b=c+d=这个边长。这里我采用的是双指针法。两个指针从两段向中间移动,就可以顺便统计出有多少对木棍符合条件。于是ans+=C(最长的木棍的条数,2)*C(符合条件的对数,2),当然,别忘了去重!

如果是3+1+1+1,我们依旧是枚举最长的那3根木棍。然后问题就变成了如何在一堆木棍中选出3根使得长度之和为一个定值。这个显然是O(n3)的背包啊,而我们要的是O(n2)的复杂度,怎么办?

看来我们枚举最长棍的做法不太可行,那么我们可以换个角度,枚举3条短棍中最长的那一条。那么我们可以用s[i]表示在之前的木棍中,选出两根使得长度之和为i的方案数。这样,我们在枚举到i的时候,先枚举i后面的所有木棍j,判断一下j能否成为最长的木棍,也就是判断s[j的长度-i的长度]是否为0。如果是,则更新答案;枚举完j后,我们再用i来更新s数组,这就变成了一个背包问题。

然而考试的时候大佬们都是用容斥来处理的3+1+1+1,感觉容斥学的不好,没太听懂~

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
int n,m;
ll ans,sum,cnt;
int v[5010],val[5010],num[5010],bel[5010];
int s[10000010];
int main()
{
//freopen("yist.in","r",stdin);
//freopen("yist.out","w",stdout);
scanf("%d",&n);
int i,j,l,r;
for(i=1;i<=n;i++) scanf("%d",&v[i]);
sort(v+1,v+n+1);
for(i=1;i<=n;i++)
{
if(v[i]>v[i-1]) val[++m]=v[i];
num[m]++,bel[i]=m;
}
for(i=1;i<=m;i++)
{
if(num[i]>=2)
{
sum=cnt=0;
for(l=1,r=i-1;l<=r;l++)
{
while(l<=r&&val[l]+val[r]>val[i]) r--;
if(val[l]+val[r]!=val[i]||l>r) continue;
if(l==r)
{
if(num[l]>=4) cnt+=(ll)num[l]*(num[l]-1)*(num[l]-2)*(num[l]-3)/2/3/4;
cnt+=(ll)num[l]*(num[l]-1)/2*sum;
}
else
{
if(num[l]>=2&&num[r]>=2) cnt+=(ll)num[l]*(num[l]-1)/2*num[r]*(num[r]-1)/2;
cnt+=(ll)num[l]*num[r]*sum;
sum+=(ll)num[l]*num[r];
}
}
ans+=cnt*num[i]*(num[i]-1)/2;
}
}
for(i=1;i<=n;i++)
{
for(j=bel[i]+1;j<=m;j++) if(num[j]>=3) ans+=(ll)num[j]*(num[j]-1)*(num[j]-2)/2/3*(s[val[j]-v[i]]);
for(j=1;j<i;j++) if(v[j]+v[i]<=v[n]) s[v[j]+v[i]]++;
}
printf("%lld",ans);
return 0;
}

【BZOJ4927】第一题 双指针+DP(容斥?)的更多相关文章

  1. 【BZOJ4927】第一题 双指针+DP

    题解: 虽然是过了,不过做的十分智障 首先是有 2根 2 1 1 , 3根 1 1 1 这两种方法 然后考虑2 2 1 1 two-point-two没啥好说的 3 1 1 1 我很智障的以为数据范围 ...

  2. [Luogu P1450] [HAOI2008]硬币购物 背包DP+容斥

    题面 传送门:https://www.luogu.org/problemnew/show/P1450 Solution 这是一道很有意思的在背包里面做容斥的题目. 首先,我们可以很轻松地想到暴力做背包 ...

  3. bzoj 3622 DP + 容斥

    LINK 题意:给出n,k,有a,b两种值,a和b间互相配对,求$a>b$的配对组数-b>a的配对组数恰好等于k的情况有多少种. 思路:粗看会想这是道容斥组合题,但关键在于如何得到每个a[ ...

  4. 【BZOJ 4665】 4665: 小w的喜糖 (DP+容斥)

    4665: 小w的喜糖 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 94  Solved: 53 Description 废话不多说,反正小w要发喜 ...

  5. 【做题】CF285E. Positions in Permutations——dp+容斥

    题意:求所有长度为\(n\)的排列\(p\)中,有多少个满足:对于所有\(i \,(1 \leq i \leq n)\),其中恰好有\(k\)个满足\(|p_i - i| = 1\).答案对\(10^ ...

  6. CDOJ 1294 天行廖的游戏 dp 容斥

    天行廖的游戏 题目连接: http://acm.uestc.edu.cn/#/problem/show/1294 Description 天行健,君子以自强不息.地势坤,廖爷以厚德载物 一日在喵哈哈村 ...

  7. [BZOJ 1042] [HAOI2008] 硬币购物 【DP + 容斥】

    题目链接:BZOJ - 1042 题目分析 首先 Orz Hzwer ,代码题解都是看的他的 blog. 这道题首先使用DP预处理,先求出,在不考虑每种硬币个数的限制的情况下,每个钱数有多少种拼凑方案 ...

  8. codeforces 342D Xenia and Dominoes(状压dp+容斥)

    转载请注明出处: http://www.cnblogs.com/fraud/          ——by fraud D. Xenia and Dominoes Xenia likes puzzles ...

  9. bzoj1042: [HAOI2008]硬币购物(DP+容斥)

    1600+人过的题排#32还不错嘿嘿 浴谷夏令营讲过的题,居然1A了 预处理出f[i]表示购买价值为i的东西的方案数 然后每次询问进行一次容斥,答案为总方案数-第一种硬币超限方案-第二种超限方案-第三 ...

随机推荐

  1. TCP/IP协议组随笔

    原文:https://my.oschina.net/xianggao/blog/654677 IP层负责网络主机的定位,数据传输的路由,由IP地址可以唯一的确定Internet上的一台主机. TCP层 ...

  2. 【Linux】使用xshell登陆时密码框为灰色,无法输入密码

    使用xshell登陆时,出现以上情况,那么这到底值咋回事呢?经过查询以后发现是服务器端设置问题,解决办法如下: vi /etc/ssh/sshd_config 接着保存退出,然后重启sshd服务 se ...

  3. Jenkins Docker 插件

    原文地址:https://wiki.jenkins.io/display/JENKINS/Docker+Plugin Created by magnayn -, last modified by Ni ...

  4. 工作总结 用, 隔开数据 后台不可以用 List<string> 接收 get请求直接通过浏览器发请求传数组或者list到后台

    旁边的 css js 为项目的 加载 css js 地址 只加载引用的样式 js http://localhost:8736/LinInFoKPI/ExcelPrint?line=&start ...

  5. Android项目:使用pulltorefresh开源项目扩展为下拉刷新上拉加载更多的处理方法,监听listview滚动方向

    很多android应用的下拉刷新都是使用的pulltorefresh这个开源项目,但是它的扩展性在下拉刷新同时又上拉加载更多时会有一定的局限性.查了很多地方,发现这个开源项目并不能很好的同时支持下拉刷 ...

  6. 安装Geo-IP

    安装指令例如以下所看到的,跟着步骤一步一步运行就可以.使用root权限,假设不是的话,请依据情况加上sudo权限命令. cd /tmp wget http://geolite.maxmind.com/ ...

  7. iOS swift objc_setAssociatedObject和objc_getAssociatedObject使用

    oc中的AssociationsManager在swift中也是可以实现的 使用方法请看下面一个例子 import UIKit extension UIButton { func fk_addActi ...

  8. C语言include预处理命令与多文件编译

    #include预处理命令几乎使我们在第一次接触C的时候就会碰到的预处理命令,可我现在还不怎么清楚,这次争取一次搞懂. 一.#include预处理指令的基本使用 预处理指令可以将别处的源代码内容插入到 ...

  9. Android Studio SDK Manager 解决无法更新问题

    一.首先要保证你可以FQ上google等网站. 这个..如何越过GFW就要靠自己了..网上也有很多教程.. 二.更改android sdk manager的option设置 选择Tools→Opini ...

  10. 如何玩转最新的项目的搭配springmvc+mybatis+Redis+Nginx+tomcat+mysql

    上一次完成nginx+tomcat组合搭配,今天我们就说说,这几个软件在项目中充当的角色: 要想完成这几个软件的组合,我们必须知道和熟悉应用这个框架, 一: Nginx:在项目中大多数作为反向代理服务 ...