正解:计数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; }