原理我懂了
注意到資料範圍:
n<=
18
有什麼演算法?
暴力?狀壓!
狀壓dp,對於每只豬1和0表示是否被打掉了
設f[s]為當前狀態的最小步數
我們知道,三個點可以確定乙個拋物線
已知乙個點是原點,那麼再來兩個點就可以確定乙個拋物線,設點i和點j確定的拋物線表示為(i,j)
每次列舉乙個狀態s,再列舉兩隻豬i,j,當然i,j不在s裡面
那麼設所有經過(i,j)這條拋物線的點的集合為s』 那麼f
[s⋁s
′]=f
[s]+
1,f[
0]=1
那麼現在還需要預處理的就是每個集合s』
用a[i,j]存放拋物線(i,j)所經過的點的集合
那麼轉移方程變成了 f
[s⋁a
[i,j
](i,
j不∈s
)]=m
in( f[s⋁
a[i,
j](i
,j不∈
s)], f[s
]+1)
,f[0
]=1
時間複雜度o(
2n+n
2)臨時**,還要慢慢寫。
網上的**。為什麼我的思路跟他一樣,但通過不呢??
#include #include #include #define maxn 20
using namespace std;
const double eps=1e-7;
struct point
__attribute__((__optimize__("-o2"))) point(double x,double y):x(x),y(y){}
};point p[maxn],res;
int n,m,t;
int dp[1<=0.0) continue;
status[i][j]=(1<
#include //#define debug 1
using namespace std;
const int mm=18;
struct point;
vectorp;
int dp[1<0.0 || a<-1e-9) continue;
//還沒有考慮到 兩個點只能確定開口向上的拋物線
int s = 1<(same[i][j])<>dd&1) && (s>>ff & 1) && dd!=ff) }}
dp[s]=1;}}
for(int i=0;i( same[dd][ff]) << " ";
}cout << endl;
}#endif // debug
int dprogram()}}
}return dp[(1<> t;
while(t--));
}math();
cout << dporgram();
}return 0;
}
NOIP2016提高組day2 蚯蚓
本題中,我們將用符號 lcj 表示對 c 向下取整,例如 l3.0j l3.1j l3.9j 3 蛐蛐國最近蚯蚓成災了!隔壁跳蚤國的跳蚤也拿蚯蚓們沒辦法,蛐蛐國王只好去 請神刀手來幫他們消滅蚯蚓。蛐蛐國裡現在共有 n 只蚯蚓 n 為正整數 每只蚯蚓擁有長度,我們設第 i 只匠 蚓的長度為 ai i ...
NOIP 2016 提高組 Day2 組合數問題
是我想起了有一年考過相似的題目 當時用的是楊輝三角。思路 遞推 矩陣字首和 關於矩陣字首和 c n,m c n 1,m c n 1,m 1 就可以直接遞推出2000以內的所有的組合數。而我們只需要判斷有多少個點對滿足是k的倍數,很容易想到只要對k取模,對於為0的c i,j 是肯定滿足是k的倍數的。因...
NOIP2016提高組 day2 組合數問題
總所周知 階乘int到14就爆了long long到20也就爆了,所以說直接存肯定是不行的 在觀察一下題目發現試求組合數是k的倍數,所以說可以把k作為mod,餘數為零肯定就是k的倍數啦,否則不是。又因為由二項式定理 易得二項式展開的每一項就包涵組合數的答案。我們又已知楊輝三角其實就是二項式的係數恰好...