[2019HDU多校第一場][HDU 6578][A. Blank]


題目鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=6578

題目大意:長度為\(n\)的數組要求分別填入\(\{0,1,2,3\}\)四個數中的任意一個,有\(m\)個限制條件:區間\([l,r]\)中出現的數字種數恰好為\(x\),求方案數

題解:f[i][j][k][cur]表示四個數最后出現的位置經過排序后為\(i,j,k,cur\)的方案數,暴力轉移即可,其中最后一維需要滾動數組節省空間

   對於限制條件可以用vector存下來,每次循環對右端點為當前點的限制條件進行判斷即可

   雖然要套四個\(for\),但是由於有順序限制,所以執行次數大約為\(\frac{n^4}{24}\),加上本題的運算簡單,常數較小,因此基本不會出現TLE的情況

 

   但是還是要吐槽一句出題人把這場比賽的時間設的好死啊...開個3s應該也不至於放假算法過吧orz

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define N 101
 4 #define mp make_pair
 5 #define MOD 998244353
 6 int T,n,m,l,r,x,f[N][N][N][2],ans;
 7 vector<pair<int,int>>d[N];
 8 void init()
 9 {
10     ans=0;
11     scanf("%d%d",&n,&m);
12     for(int i=1;i<=n;i++)
13       {
14       d[i].clear();
15       d[i].push_back(mp(i,1));
16       }
17     for(int i=1;i<=m;i++)
18       {
19       scanf("%d%d%d",&l,&r,&x);
20       d[r].push_back(mp(l,x));
21       }
22     memset(f,0,sizeof(f));
23     f[0][0][0][0]=1;
24     for(int cur=1;cur<=n;cur++)
25       {
26       int o=cur&1;
27       for(int i=0;i<=cur;i++)
28         for(int j=i;j<=cur;j++)
29           for(int k=j;k<=cur;k++)
30             f[i][j][k][o]=0;
31       for(int i=0;i<=cur;i++)
32         for(int j=i;j<=cur;j++)
33           for(int k=j;k<=cur;k++)
34             {
35             (f[j][k][cur-1][o]+=f[i][j][k][o^1])%=MOD;
36             (f[i][k][cur-1][o]+=f[i][j][k][o^1])%=MOD;
37             (f[i][j][cur-1][o]+=f[i][j][k][o^1])%=MOD;
38             (f[i][j][k][o]+=f[i][j][k][o^1])%=MOD;
39             }
40       for(int i=0;i<=cur;i++)
41         for(int j=i;j<=cur;j++)
42           for(int k=j;k<=cur;k++)
43             for(auto pi:d[cur])
44               {
45               l=pi.first,r=cur,x=pi.second;
46               if((i>=l)+(j>=l)+(k>=l)+(cur>=l)!=x)
47                 f[i][j][k][o]=0;
48               }
49       }
50     for(int i=0;i<=n;i++)
51       for(int j=i;j<=n;j++)
52         for(int k=j;k<=n;k++)
53           (ans+=f[i][j][k][n&1])%=MOD;
54     printf("%d\n",ans);
55 }
56 int main()
57 {
58     scanf("%d",&T);
59     while(T--)init();
60 }
View Code

代碼中對vector的初始化其實是沒必要額外push_back的,寫的時候為了保險就加上去了(雖然差點導致TLE)

 

這竟然是我博客里的第一道純DP題...?


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM