正解:计数dp
解题报告:
umm其实我jio得dp的题目的话就难在思想昂,,,知道状态知道转移就不难辣QAQ
所以就不说别的了直接写下思路放下代码就over辣QAQ
最基础的思想就是f[i][j][k][p]:dp到第i个点了,第一种颜色最后一次出现在j第二种在k第三种在p的方案数
然后考虑显然到i一定会等于jkp中的一个鸭,所以就可以降一维,i=max{j,k,p}
然后就欧克辣?
#include<bits/stdc++.h>
using namespace std;
#define il inline
#define fr first
#define sc second
#define ll long long
#define rg register
#define gc getchar()
#define mp make_pair
#define rp(i,x,y) for(rg int i=x;i<=y;++i)
#define my(i,x,y) for(rg int i=x;i>=y;--i)
const int N=300+10;const ll mod=1e9+7;
ll f[N][N][N],as;
int n,m;
vector< pair<int,int> >lim[N];
il int read()
{
rg char ch=gc;rg int x=0;rg bool y=1;
while(ch!='-' && (ch>'9' || ch<'0'))ch=gc;
if(ch=='-')ch=gc,y=0;
while(ch>='0' && ch<='9')x=(x<<1)+(x<<3)+(ch^'0'),ch=gc;
return y?x:-x;
}
int main()
{
// freopen("rs.in","r",stdin);freopen("rs.out","w",stdout);
n=read();m=read();
rp(i,1,m){int l=read(),r=read(),x=read();lim[r].push_back(mp(l,x));}
f[1][0][0]=1;
rp(i,1,n)
{
int sz=lim[i].size();
rp(j,0,sz-1)
{
int l=lim[i][j].fr,x=lim[i][j].sc;
rp(k,0,i-1)
{
rp(p,0,max(0,k-1))
{
if(x==1 && l<=k)f[i][k][p]=0;
if(x==2 && (k<l || l<=p))f[i][k][p]=0;
if(x==3 &&p<l)f[i][k][p]=0;
}
}
}
if(i==n)continue;
rp(j,0,i-1)
{
rp(k,0,max(0,j-1))
{
if(!f[i][j][k])continue;
f[i+1][j][k]=(f[i+1][j][k]+f[i][j][k])%mod;
f[i+1][i][k]=(f[i+1][i][k]+f[i][j][k])%mod;
f[i+1][i][j]=(f[i+1][i][j]+f[i][j][k])%mod;
}
}
}
rp(j,0,n-1)rp(k,0,max(0,j-1))as=(as+f[n][j][k])%mod;
printf("%lld\n",(ll)as*3%mod);
return 0;
}