l i n k link link:添加链接描述
用 f l , r f_{l,r} fl,r 表示左右分别放到 l 、 r l、r l、r 的位置每次转移的时候考虑一下限制就行了。
如果用 f i , j f_{i,j} fi,j 表示用了前 i i i 个数字放到第 j j j 也等价,可以用 i , j i,j i,j 推出 l , r l,r l,r 细节很多的一道题
#include <bits/stdc++.h>
using namespace std;
#define rep(i,j,k) for(int i = j;i <= k;++i)
#define repp(i,j,k) for(int i = j;i >= k;--i)
#define fr first
#define se second
#define ll long long
#define gg {flag = false;break;}
int rd() {
int sum = 0;char c = getchar();bool flag = true;
while(c < '0' || c > '9') {if(c == '-') flag = false;c = getchar();}
while(c >= '0' && c <= '9') sum = sum * 10 + c - 48,c = getchar();
if(flag) return sum;
else return -sum;
}
int n,q;
ll f[100][100];
pair<pair<int,int>,int>h[110];
// 1:< 2:<= 3:= 4:> 5:>=
void pre() {
char c;
int i = 1;
while(i <= q) {
h[i].fr.fr = rd();
c = getchar(); while(c == ' ') c = getchar();
if(c == '<') h[i].se = 1;
if(c == '=') h[i].se = 3;
if(c == '>') h[i].se = 4;
c = getchar(); if(c == '=') h[i].se++;
h[i].fr.se = rd();
if(h[i].fr.fr > h[i].fr.se) {
swap( h[i].fr.fr , h[i].fr.se );
if(h[i].se == 1 || h[i].se == 2) h[i].se += 3;
else if(h[i].se == 4 || h[i].se == 5) h[i].se -= 3;
}
if(h[i].fr.fr == h[i].fr.se)
if(h[i].se == 1 || h[i].se == 4) {printf("0\n");exit(0);}
else q--;
else i++;
}
sort(h+1,h+q+1);
}
void work() {
ll ans = 0;
f[0][2*n+1] = 1;
rep(i,0,n-1) rep(l,0,2*i) {
int r = 2*n+1-(2*i-l); bool flag = true;
rep(k,1,q) if(h[k].fr.fr == l+1){
if(h[k].fr.se > r-1) {if(h[k].se <= 3) gg;}
else if(h[k].fr.se == r-1) {if(h[k].se == 1 || h[k].se == 4) gg;}
else if(h[k].se >= 3) gg;
}
if(flag)
rep(k,1,q) if(h[k].fr.fr == r-1) if(h[k].se <= 3) gg;
if(flag && i != n-1) f[l+1][r-1] += f[l][r];
flag = true;
rep(k,1,q) if(h[k].fr.fr == l+1) {
if(h[k].fr.se == l+2) {if(h[k].se == 1 || h[k].se == 4) gg;}
else if(h[k].fr.se >= r) {if(h[k].se <= 3) gg;}
else {if(h[k].se >= 3)gg;}
}
if(flag) rep(k,1,q) if(h[k].fr.fr == l+2) {
if(h[k].fr.se >= r) {if(h[k].se <= 3)gg;}
else {if(h[k].se >= 3) gg;}
}
if(flag) f[l+2][r] += f[l][r];
flag = true;
rep(k,1,q) if(h[k].fr.fr == r-2) {
if(h[k].fr.se == r-1) {if(h[k].se == 1 || h[k].se == 4) gg; }
else if(h[k].se <= 3) gg;
}
else if(h[k].fr.fr == r-1) if(h[k].se <= 3) gg;
if(i != n-1 && flag) f[l][r-2] += f[l][r];
}
rep(i,0,2*n) ans += f[i][i+1];
printf("%lld\n",ans);
}
int main() {
n = rd(); q = rd();
pre();
work();
return 0;
}