NOIP 2015 愤怒的小鸟

100 篇文章 0 订阅
57 篇文章 0 订阅

评测传送

状态压缩+dp;
我们用f[s]表示消灭掉s这个状态的猪最少需要几次。
预处理出attack[i][j],表示穿过i,j这两只小猪的曲线能打下的猪。
那么f[s]=min(f[s],f[s^(s&attack[j][k])]);

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#define LL long long
#define DO double
#define P(x) (x)*(x)
using namespace std;
const DO res=1e-6;
const int N=(1<<18);
int attack[20][20];
int f[N+10],Q,n,m;
DO X[20],Y[20];
DO work(int i,int j)//解方程 
{
    DO x=X[i],y=Y[i],xx=X[j],yy=Y[j];
    DO s;
    s=(xx*y-x*yy)/(x*xx*(x-xx));
    return s;
}
int main()
{
    scanf("%d",&Q);
    while(Q--)
    {
        memset(attack,0,sizeof(attack));
        //memset(f,127/3,sizeof(f));
        scanf("%d%d",&n,&m);
        for(int i=0;i<n;i++) scanf("%lf%lf",&X[i],&Y[i]);
        for(int i=0;i<n;i++)
         for(int j=0;j<n;j++)
         if(i!=j)
         {
             int s=0; 
             DO a=work(i,j);
             DO b=(Y[i]-X[i]*X[i]*a)/X[i];//解方程 
             //printf("%lf  %lf\n",a,b);
             if(a<=res)
             for(int k=0;k<n;k++)
             {
                if(fabs(a*P(X[k])+b*X[k]-Y[k])<=res)
                 s=s|(1<<k);
             }
             attack[i][j]=s;
         }//预处理 

         f[0]=0;
         int i,j;
         for(i=1;i<(1<<n);i++)
         {
             for(j=0;j<n;j++)
              if((1<<j)&i) break;//找到i状态下第一个活着的猪

             f[i]=f[i^(1<<j)]+1;  
             for(int k=0;k<n;k++)
             if(k!=j&&(1<<k)&i)
             {
                f[i]=min(f[i],f[i^(i&attack[j][k])]+1);
             }
         }
         printf("%d\n",f[(1<<n)-1]);
    }
    //cout<<N; 
    return 0;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值