老w是個棋藝高超的棋手,他最喜歡的棋子是馬,更具體地,他更加喜歡馬所行走的方式。老w下棋時覺得無聊,便決定加強馬所行走的方式,更具體地,他有兩雙手,其中一雙手能讓馬從(u,v)移動到(u+ax,v+ay)而另一雙手能讓馬從(u,v)移動到(u+bx,v+by)。小w看見老w的下棋方式,覺得非常有趣,他開始思考乙個問題:假設棋盤是個無限大的二維平面,一開始馬在原點(0,0)上,若用老w的兩種方式進行移動,他有多少種不同的移動方法到達點(ex,ey)呢?兩種移動方法不同當且僅當移動步數不同或某一步所到達的點不同。老w聽了這個問題,覺得還不夠有趣,他在平面上又設立了n個禁止點,表示馬不能走到這些點上,現在他們想知道,這種情況下馬有多少種不同的移動方法呢?答案數可能很大,你只要告訴他們答案模(10^9+7)的值就行。
馬攔過河卒的公升級版本
這裡很明顯得解一下ax+by=c這樣的方程,然後這樣就可以轉化為經典的o(x*y)dp
但是本題x*y巨大
我們發現如果是
這樣不妨對干涉點排序
考慮dp:
減去所有起始點到當前選擇干涉點*當前跟新干涉點的組合數
#includeusing namespace std;
typedef int int;
#define int long long
const int mod=1e9+7;
const double eps=1e-8;
const int n=1e6+1000;
int ex,ey;
int ax,ay,bx,by;
int x,y;
int n;
double a[4][4];
struct nodea[n];
bool cmp (node a,node b)
for(int j=1;j<=2+1;j++)
if(fabs(a[i][i])=0;--i)
}int c(int n,int m)
int ans=0;
int g[511][511];
int f[511];
inline void build(int &x,int &y)
n++;
// cout<
a[n].x=ex;
a[n].y=ey;
sort(a+1,a+1+n,cmp);
graph();
for(int i=1;i<=n;++i)
} cout<
return 0;
}
省選專練SCOI2005掃雷
這是乙個智商檢測題 狀壓dp。如果你玩過掃雷,並且內心有一棵平衡樹 bb數 你就會發現答案只有0,1,2共計三種。於是法一 模擬。答案對不對只會取決於第乙個是什麼。模擬兩邊就好了。includeusing namespace std int i,j,k,m,n,ans 2,a 10001 b 100...
省選專練ZJOI2005午餐
這是個好題 考察dp優化,dp,貪心,01揹包變種。好首先對吃飯時間從大到小排序,因為一隊人打飯時長總和一樣。dp i,j 表示前i個人,第一組用j的時間。放第乙個揹包 dp i j min max dp i 1 j a i w j a i v 放第二個揹包 dp i j min max dp i ...
省選專練ZJOI2012旅遊
stl在開o2後自然是大水題。考點 樹的直徑。第一二次構圖。把每乙個三角塊相鄰的建邊。怎麼建?stl 你都做到這個題了map hash兩個值鐵定會吧。但是zjoi沒有那麼好心,不過你也有70分了。於是這樣 把兩點建邊。排個序。相同的時候連起來。樹的直徑。很多人求複雜了。樹的直徑一遍dfs就可以,不需...