ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

luogu P2831 [NOIP2016 提高组] 愤怒的小鸟

2020-12-31 22:03:15  阅读:208  来源: 互联网

标签:NOIP2016 nn luogu 状压 T2 P2831 include dp define


题面传送门
数据这么小显然状压dp
考虑状压\(dp_i\)表示打掉的集合为\(i\)时最少抛物线条数。
预处理\(f_{i,j}\)表示过\(i\)点和\(j\)点的抛物线经过的点的集合。
但是这样的转移是\(O(T2^nn^2)\)的。
考虑怎么优化。
很明显我们的\(dp\)转移是无序的。将其变成有序即先打最小的点则可优化掉一个\(n\)变为\(O(T2^nn)\)
代码实现:

#include<cstdio>
#include<cstring>
#define abs(x) ((x)>0?(x):-(x))
#define min(a,b) ((a)<(b)?(a):(b))
#define eps 1e-6
using namespace std;
int n,m,dp[1000039],g[1000039],t,a,b,f[39][39];
double x[39],y[39],nowx,nowy,x1,x2,y1,y2;
int main(){
//	freopen("1.in","r",stdin);
	register int i,j,k;
	scanf("%d",&t);
	for(i=0;i<(1<<18);i++){
		for(j=1;j<=18;j++) if(!(i&(1<<j-1))){g[i]=j;break;}
	}
	while(t--){
		scanf("%d%d",&n,&m);memset(dp,0x3f,sizeof(dp));dp[0]=0;
		for(i=1;i<=n;i++) scanf("%lf%lf",&x[i],&y[i]),dp[(1<<i-1)]=1;
		for(i=1;i<=n;i++){
			for(j=1;j<=n;j++){
				f[i][j]=0;
				x1=x[i];x2=x[j];y1=y[i];y2=y[j];
				if(abs(x1-x2)<=eps) continue;
				nowx=(y1*x2-y2*x1)/(x1*x1*x2-x2*x2*x1);
				nowy=(y1-nowx*x1*x1)/x1;
				if(nowx>0) continue;
				for(k=1;k<=n;k++) 
				if(abs(nowx*x[k]*x[k]+nowy*x[k]-y[k])<=eps) f[i][j]|=1<<k-1;
			}
		}
		for(i=0;i<(1<<n)-1;i++){
			for(j=1;j<=n;j++) dp[i|f[g[i]][j]]=min(dp[i|f[g[i]][j]],dp[i]+1);
			for(j=1;j<=n;j++) dp[i|(1<<j-1)]=min(dp[i|(1<<j-1)],dp[i]+1);
		}
		printf("%d\n",dp[(1<<n)-1]);
	}
}

标签:NOIP2016,nn,luogu,状压,T2,P2831,include,dp,define
来源: https://www.cnblogs.com/275307894a/p/14218754.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有