Tsinsen A1210 光稜坦克——動態規劃+字首和優化
阿新 • • 發佈:2018-12-13
題意
- 一個平面直角座標系上,有N個點,標號為1到N,其中第i個點的座標為(x[i], y[i])。 求滿足以下兩個條件的點列{p[i]}的數目(假設{p[i]}的長度為M) (1) 對任意1 <= i < j <= M,必有y[p[i]] > y[p[j]]; (2) 對任意3 <= i <= M,必有x[p[i-1]] < x[p[i]] < x[p[i-2]]或者x[p[i-2]] < x[p[i]] < x[p[i-1]]。 求滿足條件的非空序列{p[i]}的數目,結果對一個整數Q取模。
對於第一個限制很容易會想到對進行排序
但是這樣子空間是的,過不了這個卡空間的題
那麼我們考慮對進行排序
設為號點起始
向左或向右延伸的方案數
那麼我們每次新增一個新點一定是橫座標最大的
那麼它只能放在第一個或者第二個
那麼我們列舉這個點前面的點
如果它的縱座標小於當前新加的點 那麼當前點就是第一個點
那麼我們把列舉點右邊的點全部加入當前點的左邊
如果它的縱座標大於當前新加的點 列舉點就是第一個點
我們把當前點左邊的點全部加入列舉點的右邊
然後就做完了 時間複雜度空間複雜度
Codes
#include<bits/stdc++.h>
#define file(s) freopen(s".in", "r", stdin), freopen(s".out", "w", stdout)
#define go(x, i) for(register int i = head[x]; i; i = nxt[i])
#define For(i, a, b) for(register int i = (a), i##_end_ = (b); i <= i##_end_; ++ i)
#define FOR(i, a, b) for(register int i = (a), i##_end_ = (b); i >= i##_end_; -- i)
#define debug(x) cout << #x << " = " << x << endl
#define mem(a, b) memset(a, b, sizeof(a))
#define cpy(a, b) memcpy(a, b, sizeof(a))
#define min(a, b) (a < b ? a : b)
#define max(a, b) (b < a ? a : b)
#define inf (0x3f3f3f3f)
#define INF (1e18)
#define pb push_back
#define mp make_pair
#define x first
#define y second
typedef unsigned long long ull;
typedef unsigned int uint;
typedef long long ll;
typedef std::pair<ll, int> PLI;
typedef std::pair<int, int> PII;
typedef long double ldb;
typedef double db;
template<class T>inline bool chkmax(T &_, T __) {return _ < __ ? _ = __, 1 : 0;}
template<class T>inline bool chkmin(T &_, T __) {return _ > __ ? _ = __, 1 : 0;}
using namespace std;
const int N = 7e3 + 10;
int f[N][2], n, ans, mod;
struct Point {
int x, y;
bool operator < (const Point &T) const {
return x < T.x;
}
}A[N];
int main() {
#ifdef ylsakioi
file("refract");
#endif
scanf("%d%d", &n, &mod); For(i, 1, n) scanf("%d%d", &A[i].x, &A[i].y);
ans = mod - n; sort(A + 1, A + n + 1);
For(i, 1, n) {
f[i][0] = f[i][1] = 1;
FOR(j, i - 1, 1) {
if(A[i].y > A[j].y) (f[i][0] += f[j][1]) %= mod;
if(A[j].y > A[i].y) (f[j][1] += f[i][0]) %= mod;
}
}
For(i, 1, n) (ans += (f[i][0] + f[i][1]) % mod) %= mod;
cout << ans << endl;
return 0;
}