JZOJ-senior-3512. 【NOIP2013模拟11.5A组】游戏节目(show)
2018-01-11 18:38
330 查看
3512. 【NOIP2013模拟11.5A组】游戏节目(show)
(File IO): input:show.in output:show.outTime Limits: 1000 ms Memory Limits: 262144 KB Detailed Limits
Description
有三支队伍,分别是A,B,C。有n个游戏节目,玩第i个游戏,队伍A可以得到的分数是A[i],队伍B可以得到的分数是B[i],队伍C可以得到的分数是C[i]。由于时间有限,可能不是每个节目都能玩,于是节目主持人决定要从n个游戏节目里面挑选至少k个节目出来(被选中的节目不分次序),使得队伍A成为赢家。队伍A能成为赢家的条件是队伍A的总得分要比队伍B的总得分要高,同时也要比队伍C的总得分要高。节目主持人有多少种不同的选取方案?
Input
第一行,两个整数n和k。
第二行, n个整数,分别是A[1]、A[2]、A[3]…A
。
第三行, n个整数,分别是B[1]、B[2]、B[3]…B
。
第四行, n个整数,分别是C[1]、C[2]、C[3]…C
。
Output
一个整数,表示不同的选取方案数量。
Sample Input
3 2
1 1 2
1 1 1
1 1 1
Sample Output
3
【样例解释】
方案一:选取节目1和节目3。 方案二:选取节目2和节目3。 方案三:选取节目1、节目2、节目3。
Data Constraint
对于40%数据,2 <= n <= 20。
对于100%数据,2 <= n <= 34, 1 <= k <= min(n,7), 1 <=A[i], B[i], C[i]<= 10^9。
题解
分两步处理:第一步:把问题简单化,假设没有k的限制,设求出来的方案总数是x。
第二步:考虑k的限制,由于k<7,可以穷举n个节目取0个,n个节目取1个,n个节目取2个,n个节目取3个,n个节目取3个,n个节目取4个,n个节目取5个,n个节目取6个,穷举完这几种情况就可以知道哪些方案是合法的。而且Combinations(34,0) + Combinations(34,1) + Combinations(34,2) + Combinations(34,3) + Combinations(34,4) + Combinations(34,5) + Combinations(34,6) = 1676116。
也就是这个穷举不超过1676116次。设第二步的方案总数是y。
那么,最后应该输出的答案就是x - y。
第二步的方案数y可以搜索计算结果,下面重点讲讲第一步的方案数x如何求。
由于n最大是34,直接搜索会超时。可以把n个节目平均分成两部分,即第1至第n/2个节目归为第1部分,第n/2+1个节目至第n个节目归为第2部分。
第1部分:显然最多只有17个节目,每个节目可以取或者不取,穷举这17个节目的所有情况,显然有2^17种取法,对于每一种取法,队伍A都有一个得分,设为scoreA, 队伍B也有一个得分scoreB,队伍C也有一个得分scoreC。不妨设difAB1 = scoreA - scoreB, difAC1 = scoreA - scoreC,即每一种取法,都可以计算出一对值(difAB1,difAC1),
第2部分:显然最多也只有17个节目。每个节目可以取或者不取,穷举这17个节目的所有情况,显然也是有2^17种取法。同理,对于每一种取法,设difAB1 = scoreA - scoreB, difAC1 = scoreA - scoreC,即每一种取法都可以计算出一对值(difAB2,difAC2),
显然,如果一个方案要成立,必须要同时满足:
difAB1 + difAB2 > 0 (即队伍A的总得分比队伍B的总得分高)
difAC1 + difAC2 > 0 (即队伍A的总得分比队伍C的总得分高)
于是,问题转化为,枚举一对值(difAB1,difAC1),在第2部分里面查询有多少对(difAB2,difAC2),使得同时满足
difAB1 + difAB2 > 0
difAC1 + difAC2 > 0
显然,对于第2部分,可以用树状数组或者线段树之类的数据结构进行保存,以备第1部分的查询所需。
由于分两步求答案,于是时间复杂度 = x + y = 2^17 * Log(2^17) + 1676116
Code
#include<algorithm> #include<iostream> #include<cstring> #include<cstdio> #define N 40 #define M 150000 #define ll long long #define fo(i,a,b) for(i=a;i<=b;i++) using namespace std; ll i,j,n,k,s,t1,t2,ans1,ans2; ll a ,b ,c ,tr[4*M]; ll ab1[M],ac1[M],ab2[M],ac2[M]; struct node{ll x,y,z;}d[2*M]; void dg(ll w,ll l,ll x,ll y,ll z) { if (w>i) {if (x>y && x>z) ans1++; return;} for(ll j=l+1; j<=n; j++) dg(w+1,j,x+a[j],y+b[j],z+c[j]); } void dfs1(ll l,ll x,ll y,ll z) { t1++,ab1[t1]=x-y,ac1[t1]=x-z; for(ll j=l+1; j<=n/2; j++) dfs1(j,x+a[j],y+b[j],z+c[j]); } void dfs2(ll l,ll x,ll y,ll z) { t2++,ab2[t2]=y-x,ac2[t2]=z-x; for(ll j=l+1; j<=n; j++) dfs2(j,x+a[j],y+b[j],z+c[j]); } bool cmd(node p,node q) { return p.y<q.y; } bool cmp(node p,node q) { return p.x<q.x || p.x==q.x && p.y<q.y; } void find(ll x,ll st,ll en,ll l,ll r) { if (l>r) return; if (st==l && en==r) {s+=tr[x]; return;} ll m=(st+en)>>1; if (r<=m) find(x+x,st,m,l,r); else if (l>m) find(x+x+1,m+1,en,l,r); else find(x+x,st,m,l,m),find(x+x+1,m+1,en,m+1,r); } void change(ll x,ll l,ll r,ll p) { if (l==r) {tr[x]++; return;} ll m=(l+r)>>1; if (p<=m) change(x+x,l,m,p); else change(x+x+1,m+1,r,p); tr[x]=tr[x+x]+tr[x+x+1]; } int main() { freopen("show.in","r",stdin); freopen("show.out","w",stdout); scanf("%lld%lld",&n,&k); fo(i,1,n) scanf("%lld",&a[i]); fo(i,1,n) scanf("%lld",&b[i]); fo(i,1,n) scanf("%lld",&c[i]); fo(i,1,k-1) dg(1,0,0,0,0); dfs1(0,0,0,0); dfs2(n/2,0,0,0); fo(i,1,t1) d[i].x=ab1[i],d[i].y=ac1[i],d[i].z=1; fo(i,1,t2) d[i+t1].x=ab2[i],d[i+t1].y=ac2[i],d[i+t1].z=2; sort(d+1,d+1+t1+t2,cmd); ll e=1,l=1; d[t1+t2+1].y=-2147483647; fo(i,2,t1+t2+1) if (d[i].y!=d[i-1].y) { fo(j,l,i-1) d[j].y=e; e++,l=i; } e--; sort(d+1,d+1+t1+t2,cmp); ll g,o=0; while (o<=t1+t2) { g=d[o].x,l=o; while (d[o].x==g && o<=t1+t2) o++; fo(i,l,o b870 -1) if (d[i].z==1) s=0,find(1,1,e,1,d[i].y-1),ans2+=s; fo(i,l,o-1) if (d[i].z==2) change(1,1,e,d[i].y); } printf("%lld",ans2-ans1); }
相关文章推荐
- JZOJ-senior-3502. 【NOIP2013模拟11.4B组】方格游戏
- 【NOIP2013模拟11.5A组】游戏节目
- JZOJ-senior-3423. 【NOIP2013模拟】Vani和Cl2捉迷藏
- [jzoj]3511. 【NOIP2013模拟11.5A组】cza的蛋糕(cake)(DP嵌套dfs【快】或DP【慢】)
- JZOJ 3518. 【NOIP2013模拟11.6A组】进化序列(evolve)
- [jzoj]3505. 【NOIP2013模拟11.4A组】积木(brick) (排列组合vsDP)
- [jzoj3472]【NOIP2013模拟联考8】匹配(match)
- [jzoj]3457. 【NOIP2013模拟联考3】沙耶的玩偶(doll)(匈牙利-二分图最大匹配)
- JZOJ3425. 【NOIP2013模拟】能量获取(2017.8B组)
- jzoj[3521]. 【NOIP2013模拟11.7B组】道路覆盖(cover) (状压DP)
- {题解}[jzoj3413]【NOIP2013模拟】KC的瓷器
- JZOJ 3506. 【NOIP2013模拟11.4A组】善良的精灵
- jzoj 3467. 【NOIP2013模拟联考7】最长上升子序列(lis) dfs+lis+手工栈
- [jzoj]3472. 【NOIP2013模拟联考8】匹配(match)(AC自动机+DP)
- [jzoj]3479. 【NOIP2013模拟联考9】工作安排(work)
- jzoj. 3519. 【NOIP2013模拟11.6A组】灵能矩阵(pylon)
- [jzoj]3486. 【NOIP2013模拟联考10】道路改建(rebuild)(缩环+Tarjan+拓扑+bitset记录状态)
- [jzoj]3480. 【NOIP2013模拟联考9】阿Q的停车场(park)(线段树+堆)
- [JZOJ3395]【NOIP2013模拟】Freda的传呼机
- jzoj3453【NOIP2013中秋节模拟】连通块(connect,并查集,二维)