【悬赏关注】斗地主 66 分 WA 34

P2540 [NOIP2015 提高组] 斗地主 加强版

76了 ```cpp #include<bits/stdc++.h> // #define int long long using namespace std; int sum[100],T,n,f[60][60][60][60],ans=1e18; int dp(int a,int b,int c,int d){ // cout<<a<<" "<<b<<" "<<c<<" "<<d<<"\n"; if(!a && !b && !c && !d) return 0; if(f[a][b][c][d]<0x3f3f3f) return f[a][b][c][d]; int now=a+b+c+d;//都出单排 if(a>=2 && sum[0]==2) now--;//有一个火箭 f[a][b][c][d]=min(f[a][b][c][d],now);//更新 if(d && a>=2) f[a][b][c][d]=min(f[a][b][c][d],dp(a-2,b,c,d-1)+1);//四带二 if(d && b) f[a][b][c][d]=min(f[a][b][c][d],dp(a,b-1,c,d-1)+1);// 四带二 if(d && a && c) f[a][b][c][d]=min(f[a][b][c][d],dp(a-1,b+1,c-1,d-1)+1); if(d && c) f[a][b][c][d]=min(f[a][b][c][d],dp(a+1,b,c-1,d-1)+1); if(d>=2 && a) f[a][b][c][d]=min(f[a][b][c][d],dp(a-1,b,c+1,d-2)+1); if(d && c>=2) f[a][b][c][d]=min(f[a][b][c][d],dp(a,b+2,c-2,d-1)+1); if(b && c) f[a][b][c][d]=min(f[a][b][c][d],dp(a,b-1,c-1,d)+1); if(a && c) f[a][b][c][d]=min(f[a][b][c][d],dp(a-1,b,c-1,d)+1); if(c>=2) f[a][b][c][d]=min(f[a][b][c][d],dp(a+1,b,c-2,d)+1); if(c>=2) f[a][b][c][d]=min(f[a][b][c][d],dp(a,b+1,c-2,d)+1); if(d && b>=2) f[a][b][c][d]=min(f[a][b][c][d],dp(a,b-2,c,d-1)+1); if(d && c>=2) f[a][b][c][d]=min(f[a][b][c][d],dp(a+2,b,c-2,d-1)+1); if(d && c && b) f[a][b][c][d]=min(f[a][b][c][d],dp(a+1,b-1,c-1,d-1)+1); if(d>=2) f[a][b][c][d]=min(f[a][b][c][d],dp(a,b,c,d-2)+1); return f[a][b][c][d]; } int get(){ int x[5]={0}; for(int i=3;i<=15;i++) x[sum[i]]++; x[1]+=sum[0]; return dp(x[1],x[2],x[3],x[4]); } void dfs(int step){ if(step>ans) return ; int t=get(); // system("pause"); if(step+t<ans) ans=step+t; //单顺 for(int i=3;i<=10;i++){ int pos=i; while(sum[pos]>=1) pos++; // cout<<pos<<"\n"; for(int j=i+4;j<pos;j++){ // cout<<114514<<"\n"; for(int k=i;k<=j;k++){ sum[k]--; } dfs(step+1); for(int k=i;k<=j;k++){ sum[k]++; } } } //双顺 for(int i=3;i<=12;i++){ int pos=i; while(sum[pos]>=2) pos++; for(int j=i+2;j<pos;j++){ for(int k=i;k<=j;k++){ sum[k]-=2; } dfs(step+1); for(int k=i;k<=j;k++){ sum[k]+=2; } } } //三顺 for(int i=3;i<=13;i++){ int pos=i; while(sum[pos]>=3) pos++; for(int j=i+1;j<pos;j++){ for(int k=i;k<=j;k++){ sum[k]-=3; } dfs(step+1); for(int k=i;k<=j;k++){ sum[k]+=3; } } } return ; } void solve(){ memset(sum,0,sizeof(sum)); memset(f,0x3f,sizeof(f)); for(int i=1;i<=n;i++){ int x,y; cin>>x>>y; if(x==1) x=14; if(x==2) x=15; sum[x]++; } // for(int i=0;i<=15;i++) cout<<sum[i]<<" "; // cout<<"\n"; dfs(0); // for(int i=0;i<=15;i++){ // if(sum[i]) ans++; // } cout<<ans<<"\n"; return ; } signed main(){ cin>>T>>n; while(T--){ ans=1e18; solve(); } return 0; } ```
by wangyi_c @ 2023-03-04 11:00:38


@[wangyi_c](/user/560044) 似乎没判双王算单排出还是对排出的情况。
by Isuki @ 2023-03-04 11:03:26


两种情况答案要取小的
by Isuki @ 2023-03-04 11:03:54


@[Isuki](/user/441693) ````if(a>=2 && sum[0]==2) now--;//有一个火箭 ```` 不是这个吗?
by wangyi_c @ 2023-03-04 11:04:40


@[wangyi_c](/user/560044) 意思是四带双王这种情况没有考虑
by Isuki @ 2023-03-04 11:06:21


@[Isuki](/user/441693) 好的
by wangyi_c @ 2023-03-04 11:09:02


@[Isuki](/user/441693) 过了,谢谢,已关注
by wangyi_c @ 2023-03-04 11:09:34


此帖结
by wangyi_c @ 2023-03-04 11:09:52


还有没有什么能够再优化的方法?@[Isuki](/user/441693)
by wangyi_c @ 2023-03-04 11:30:15


....exlg 警告了 `[可疑] 调用系统函数` 难崩
by jasonshen_ @ 2023-08-11 08:48:37


|