1. 程式人生 > >cf 1110 D

cf 1110 D

bsp 卸載 pre 兩個 超過 one 分享圖片 check opened

哇真難啊,沒註意到 可以開 dp[N][3][3]這種性質,也就是三個相同的順子可以變成三個刻子,所以我們維護順子的數目就不用超過三了,又因為每張牌i,只會被i-1,i-2,影響,所以額外開兩維記錄(記錄的信息在下面)就夠了。

開始也想到了對子和順子那題,,但是那題記得學長講的是堆棧做法,,,這個一看就是dp,就感覺很蔔。

哇雀魂白玩了!雀魂!卸載!

看的官方題解,還是挺好懂的。

意思就是 用 f[i][t1][t2] 表示到考慮到i這個位置, t1表示[i-1,i,i+1]的數量,t2表示[i,i+1,i+2]的數量,t3表示[i+1.i+2,i+3]的數量。

然後我們就可以 dp[i+1][t2][t3]=max(dp[i][t1][t2]+t3+ (num[i+1]-need)/3 );這樣維護下去。

還有別的dp方法,我不會。

我老人家昨晚又表演了兩個小時小品。。。感覺很搞笑哇。九點半起床讀了讀題。。

為什麽大家都會E啊,我覺得好難啊。。。

技術分享圖片
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int N=1e6+5;
 4 int n,m,a,num[N];
 5 int f[N][3][3];
 6 bool check(int i,int t1,int t2,int t3){
 7     return num[i+3]>=t3&&num[i+2]>=t2+t3&&num[i+1
]>=t1+t2+t3&&num[i]>=t1+t2&&num[i-1]>=t1; 8 } 9 int main(){ 10 ios::sync_with_stdio(false); 11 cin>>n>>m; 12 for(int i=1;i<=n;i++){ 13 cin>>a; 14 num[a]++; 15 } 16 int ans=0; 17 for(int i=0;i<=m;i++) { 18 for
(int t1=0;t1<3;t1++){ 19 for(int t2=0;t2<3;t2++){ 20 for(int t3=0;t3<3;t3++){ 21 if(check(i,t1,t2,t3)) 22 f[i+1][t2][t3]=max(f[i+1][t2][t3],f[i][t1][t2]+t3+(num[i+1]-t1-t2-t3)/3); 23 } 24 } 25 } 26 } 27 cout<<f[m+1][0][0]<<endl; 28 }
View Code

cf 1110 D