高次元DPをやる
dp[300][300][300]を作るのは雰囲気でそうなるが、工夫しないとMLEをするので頑張る
- #include<iostream>
- #include<algorithm>
- #include<vector>
- #include<queue>
- #define mod 1000000007;
- #define lol(i,n) for(int i=0;i<n;i++)
- typedef long long ll;
- using namespace std;
- ll dp[303][303][303];
- int rest[310][4];
- bool Cando(int a,int b,int c){
- int e1=max(a,max(b,c));
- int e3=min(a,min(b,c));
- int e2=a+b+c-e1-e3;
- if(rest[e1][1]<=e2&&e2<rest[e1][0]&&rest[e1][3]<=e3&&e3<rest[e1][2]){
- return true;
- }
- return false;
- }
- int main(){
- int n,m;
- cin>>n>>m;
- lol(i,n+1){
- rest[i][0]=mod;//left1
- rest[i][2]=mod;//left2
- rest[i][1]=-1;//right2
- rest[i][3]=-1;//right3
- }
- lol(i,m){
- int a,b,c;
- cin>>a>>b>>c;
- if(c==1)rest[b][0]=min(rest[b][0],a);
- if(c==3)rest[b][3]=max(rest[b][3],a);
- if(c==2){
- rest[b][1]=max(rest[b][1],a);
- rest[b][2]=min(rest[b][2],a);
- }
- }
- lol(i,n+1)lol(j,n+1)lol(k,n+1)dp[i][j][k]=0;
- dp[0][0][0]=1;
- for(int len=0;len<=n;len++){
- for(int i=0;i<max(1,len);i++){
- for(int j=0;j<max(1,i);j++){
- int R=len,G=i,B=j;
- if(Cando(R,G,B)==false)continue;
- int a=len+1,b=G,c=B;
- int e1=max(a,max(b,c));
- int e3=min(a,min(b,c));
- int e2=a+b+c-e1-e3;
- dp[e1][e2][e3]+=dp[R][G][B];
- dp[e1][e2][e3]%=mod;
- a=R,b=len+1,c=B;
- e1=max(a,max(b,c));
- e3=min(a,min(b,c));
- e2=a+b+c-e1-e3;
- dp[e1][e2][e3]+=dp[R][G][B];
- dp[e1][e2][e3]%=mod;
- a=R,b=G,c=len+1;
- e1=max(a,max(b,c));
- e3=min(a,min(b,c));
- e2=a+b+c-e1-e3;
- dp[e1][e2][e3]+=dp[R][G][B];
- dp[e1][e2][e3]%=mod;
- }
- }
- }
- ll ans=0;
- for(int i=0;i<n;i++){
- for(int j=0;j<max(i,1);j++){
- if(Cando(n,i,j)){
- ans+=dp[n][i][j];
- ans%=mod;
- }
- }
- }
- ans%=mod;
- cout<<ans<<endl;
- return 0;
- }
無理にコードを短くしないようにする
(愚直に分かりやすく書く)