對於每兩隻豬,只要他們的橫座標不一樣,就會有一條經過原點的二次函式y=
ax2+
bx同時經過這兩隻豬,那麼這時就是解二元一次方程的時候了,設第一只豬的座標為(x1,y1),第二隻豬的座標為(x2,y2) y1
=ax1
2+bx
1 y2
=ax2
2+bx
2 化為 b=y
1−ax
12x1
=y2−
ax22
x2 a
=y1−
bx1x
12=y
2−bx
2x22
得 x2
y1−a
x12x
2=x1
y2−a
x22x
1 y1
x22−
bx1x
22=y
2x12
−bx2
x12
移項合併同類項 (x
12x2
−x22
x1)a
=x2y
1−x1
y2 (
x12x
2−x2
2x1)
b=y2
x12−
y1x2
2 可以得出a和b的式子 a=
x2y1
−x1y
2x1x
2(x1
−x2)
b=y2x12
−y1x
22x1
x2(x
1−x2
) 當a<0時,此函式為過原點拋物線
當一堆豬滿足,任意一對的a和b分別相等,才可以被乙隻鳥一次性射中。
很明顯的狀壓dp:
設f[i][s] s為狀態,i表示1~i都被選了,
對於乙個集合p,裡面的元素都被選中,i∈p,且滿足要求,p裡元素狀態為k,f[i][s or k]=min(f[i][s or k],f[i-1][s]+1)
#include
#include
#include
#include
using
namespace
std;
int g[20][20],f[20][300000],n,t,m;
double a[20][2],d[20][20][2];
bool com(double x,double y)
void dfs(int lim,int v,int w)
return;
}dfs(lim,v,w+1);
dfs(lim,v+(1
<
}int main()
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
if(i!=j)
}for(int len=1;len<=n;len++)
for(int i=1;i<=n-len+1;i++)
}f[0][0]=0;
for(int i=1;i<=n;i++)
printf("%d\n",f[n][(1
<1]);}}
憤怒的小鳥
qaq 狀壓dp 1表示小鳥打掉了,0表示沒打掉。dp s 表示到s狀態最少需要幾步。怎麼列舉a,b。因為c 0,只需兩隻豬即可確定一條曲線。boom i j 表示i豬和j豬確定的曲線可以打掉的豬。關於轉移 列舉狀態s中第一只沒有打掉的小豬,固定i,列舉j即可 注意初始化 include inclu...
憤怒的小鳥
憤怒的小鳥 這道題目不是一道sb的狀壓嗎。我們設f i f i f i 表示射擊狀態是i ii,最少用了多少直線。i ii的第j jj位為1 11表示射擊這個位置。然後對於每個直線跑揹包。時間複雜度 o t n22n o tn 22 n o tn22 n 但是其實有更快做法,限制i ii只能被包含最...
憤怒的小鳥
include include include include pragma comment lib,winmm.lib 函式外部全域性變數定義 int high,width 遊戲的邊界 int bird x,bird y 小鳥的位置 int bar y,bar xdown,bar xtop 障礙物...