zoukankan      html  css  js  c++  java
  • 愤怒的小鸟 —— 状压DP

    题目描述

    给定(N)个点,和形式抛物线(y = ax^2 + bx),每次可以消去抛物线上的点,问消去所有点的最少抛物线数时是多少?

    范围

    (N leq 18)

    题解

    题目相当于dancing links思想,用(n^2)个抛物线去覆盖点集,那么设(f_i)表示覆盖了第(i)列的最少行数是多少,转移:

    (f_{i|j} = min(f_i + 1,f_{i|j}))

    预处理经过任意两点的抛物线所覆盖集合即可。

    复杂度(O(T(n^3 + n2^n)))

    代码

    #include <bits/stdc++.h>
    using namespace std;
    const int N = 18;
    const double eps = 1e-8;
    struct node {
    	double x,y;
    }pos[N];
    
    int cmp(double x,double y) {
    	if(fabs(x - y) < eps) return 0;
    	if(x < y) return -1;
    	return 1;
    }
    int n,m;
    int path[N][N];
    int f[1 << N];
    int main () {
    	int T;
    	cin >> T;
    	while(T --) {
    		cin >> n >> m;
    		for(int i = 0;i < n; ++i) {
    			cin >> pos[i].x >> pos[i].y;
    		}
    		memset(path,0,sizeof path);
    		for(int i = 0; i < n; ++i) {
    			path[i][i] = 1 << i;
    			for(int j = 0;j < n; ++j) {
    				double x1 = pos[i].x;
    				double x2 = pos[j].x;
    				double y1 = pos[i].y;
    				double y2 = pos[j].y;
    				if(!cmp(x1,x2)) continue;
    				double a = (y1 / x1 - y2 / x2) / (x1 - x2);
    				double b = y1 / x1 - a * x1;
    				if(cmp(a,0) >= 0) continue;
    				int sta = 0;
    				for(int k = 0;k < n; ++k) {
    					double xx = pos[k].x;
    					double yy = pos[k].y;
    					if(!cmp(a * xx * xx + b * xx,yy)) {
    						sta += 1 << k;
    					}
    				}
    				path[i][j] = sta;
    			}
    		}
    		memset(f,0x3f,sizeof f);
    		f[0] = 0;
    		for (int i = 0;i < (1 << n) - 1; ++i) {
    			int tmp = 0;
    			for(int j = 0;j < n; ++j) {
    				if(!(i >> j & 1)) {
    					tmp = j;
    					break;
    				}
    			}
    			for(int j = 0;j < n; ++j) {
    				f[i | path[tmp][j]] = min(f[i] + 1,f[i | path[tmp][j]]);
    			}
    		}
    		cout << f[(1 << n) - 1] << endl;
    	}
    	return 0;
    }
    
  • 相关阅读:
    c++数据类型
    c++注释
    c++基本语法
    c++环境配置
    c++简介
    9 HTTP和HTTPS
    12 RESTful架构(SOAP,RPC)
    剑指10二进制中1的个数
    第2章 新手必须掌握的Linux命令
    11个炫酷的Linux终端命令大全
  • 原文地址:https://www.cnblogs.com/Akoasm/p/15169062.html
Copyright © 2011-2022 走看看