zoukankan      html  css  js  c++  java
  • [Noip2016]愤怒的小鸟

    [Noip2016]愤怒的小鸟

    一.前言

    ​ 这题的优化确实让我学到了很多,不像某 (Archer) 的毒瘤优化题……题目链接

    二.思路

    ​ 首先看 n 知状压 DP,这个好心的抛物线……只有两个未知量,也就是只要两个点就能知道射这两个点的抛物线解析式。这里预处理一下算出来的抛物线会穿过的小猪集合……

    ​ 考虑转移,射一次,可能是盯着某一个猪去的,也可能是盯着两个猪(等效于射一群)。两个就是上限了,(除非你有红茶的箭术hhhh),本来就是转移状态枚举就好……但是有一个奇妙的优化……。

    ​ 首先挑出一只还没死的猪,为了取得答案这只猪是必死无疑的。就是说你现在不杀以后迟早得杀,并且代价都是1,那不如早杀早超生……也就如果以后的一次抉择会杀了这猪,那么我们将这两个决策顺序交换了,不影响答案。所以每次转移必杀第一个还没死的猪。这就是这个神奇的优化。

    三.CODE

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<fstream>
    #include<cmath>
    #include<cstring>
    using namespace std;
    #define dl double
    int read(){
    	char ch=getchar();
    	int res=0,f=1;
    	for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;
    	for(;ch>='0'&&ch<='9';ch=getchar())res=res*10+(ch-'0');
    	return res*f;
    }
    inline void solve(dl &a,dl &b,dl x1,dl y1,dl x2,dl y2){
    	a=(y2-y1*x2/x1)/(x2*x2-x1*x2);
    	b=(y1-a*x1*x1)/x1;
    }
    const double eps=1e-6;
    int t,n,m,maxn;
    double x[20],y[20];
    int line[20][20],dp[(1<<18)+1];
    inline int lg2(int x){
    	int cnt=-1;
    	while(x)x>>=1,cnt++;
    	return cnt;
    }
    inline int get(int x){//找出第一个没死的猪,爱咋写咋写
    	return lg2(((x)|(x+1))-x);
    }
    int main(){
    	t=read();
    	while(t--){
    		n=read();m=read();
    		memset(line,0,sizeof(line));
    		memset(dp,127/3,sizeof(dp));
    		dp[0]=0;maxn=(1<<n);
    		for(int i=0;i<n;++i)scanf("%lf%lf",&x[i],&y[i]);
    		for(int i=0;i<n;++i){
    			for(int j=i+1;j<n;++j){
    				if(fabs(x[i]-x[j])<eps)continue;//无解
    				dl a,b;
    				solve(a,b,x[i],y[i],x[j],y[j]);//计算解析式
    				if(a>-eps)continue;
    				for(int k=0;k<n;++k)
    					if(fabs(y[k]-a*x[k]*x[k]-b*x[k])<eps)line[i][j]|=(1<<k);//记录集合
    			}
    		}
    		for(int i=0;i<maxn;++i){
    			int j=get(i);
    			dp[i|(1<<j)]=min(dp[i|(1<<j)],dp[i]+1);//只射这一个
    			for(int k=j+1;k<n;++k)dp[i|line[j][k]]=min(dp[i|line[j][k]],dp[i]+1);//射一群
    		}
    		printf("%d
    ",dp[maxn-1]);
    	}
    	return 0;
    } 
    
  • 相关阅读:
    (转载)C#控件缩写规范
    ToString()格式和用法大全,C#实现保留两位小数的方法
    C#数字前面如何补0
    (转载)C#语言开发规范
    (转载)C#:Enum、Int和String的互相转换,枚举转换
    [踩坑系列]URLEncode 中对 空格的编码有 “+”和“%20”两种
    [IDEA]IDEA设置注释模板
    [Mybatis]Mybatis 常用标签及功能整理
    [设计模式]静态代理
    记一次java电话面试
  • 原文地址:https://www.cnblogs.com/clockwhite/p/13510337.html
Copyright © 2011-2022 走看看