zoukankan      html  css  js  c++  java
  • P2831 愤怒的小鸟

    P2831 愤怒的小鸟

    时隔n久,又回到了这道题。我还记得普及组时一头雾水的样子

    题外话不扯,这道题是一道比较好的dp题

    一眼就能看出来这是状态压缩。

    状态压缩dp最大的特点是什么呢?(暴力)

    我们需要暴力的枚举各种决策,然后转移

    枚举决策是个很重要的思想。也是经常考察的知识点

    所以需要多加练习

    #include<cstdio>
    #include<algorithm>
    #include<iostream>
    #include<cstring>
    using std::min;
    double x[30],y[30];
    int chance[301000],tot;
    double eps=0.00000001;
    int f[1<<(19)];
    void calc(double &A,double &B,int i,int j)
    {
    	double a=y[i],b=x[i]*x[i],c=x[i];
    	double d=y[j],e=x[j]*x[j],f=x[j];
    	A=(a*f-c*d)/(b*f-c*e);
    	B=(a*e-d*b)/(c*e-f*b);
    	return ;
    }
    double abs(double a)
    {
    	if(a<0)	return a*-1.0;
    	return a;
    }
    bool get(double a,double b,int k)
    {
    	double c=a*x[k]*x[k]+b*x[k];
    	if(abs(y[k]-c)<=eps)	
    		return true;
    	return false;
    }
    int main()
    {
    	int t;
    	scanf("%d",&t);
    	while(t--)
    	{
    		int n,m;
    		tot=0;
    		scanf("%d%d",&n,&m);//m好像在暴力面前并没有什么乱用
    		for(int i=1;i<=n;i++)
    			scanf("%lf%lf",&x[i],&y[i]);
    		for(int i=1;i<=n;i++)
    		{
    			chance[++tot]=1<<(i-1);
    			for(int j=i+1,vis=0;j<=n;j++)
    			{
    				double a,b;
    				calc(a,b,i,j);//计算函数
    				if(a>=0||vis&(1<<(j-1)))	continue;//符合现实,vis是用来去重,防止一次打掉多个的决策被重复枚举
    				int pas=0;
    				for(int k=1;k<=n;k++)
    					if(get(a,b,k)) //同时被打下
    					{
    						pas|=1<<(k-1);
    						vis|=1<<(k-1);	
    					}
    				chance[++tot]=pas;
    			}
    		}
    		memset(f,127,sizeof(f));
    		f[0]=0;
    		for(int i=0;i<(1<<n);i++)
    			for(int j=1;j<=tot;j++)
    				f[i|chance[j]]=min(f[i|chance[j]],f[i]+1);//转移
    		printf("%d
    ",f[(1<<n)-1]);	
    	}
    	
    }
    
  • 相关阅读:
    Tips:数据的单位
    PHP面向对象三大特性③
    PHP面向对象三大特性②
    PHP面向对象三大特性①
    PHP-初识面向对象
    C# 基础·算法篇
    C# 基础·常见面试
    C# 特殊处理使用方法
    C# 第三方组件使用
    JS 插件使用
  • 原文地址:https://www.cnblogs.com/Lance1ot/p/9379446.html
Copyright © 2011-2022 走看看