博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
洛谷2593 [ZJOI2006]超级麻将——可行性dp
阅读量:7049 次
发布时间:2019-06-28

本文共 4025 字,大约阅读时间需要 13 分钟。

题目:

发现三个连续牌的影响范围只有3、相同牌的影响范围只有1之后就可以dp了。

O(100^7)T飞。

#include
#include
#include
#include
using namespace std;const int N=105;int T,a[N];bool dp[2][N][N][N],flag;int rdn(){ int ret=0;char ch=getchar(); while(ch>'9'||ch<'0')ch=getchar(); while(ch>='0'&&ch<='9')(ret*=10)+=ch-'0',ch=getchar(); return ret;}int main(){ T=rdn(); while(T--) { for(int i=1;i<=100;i++)a[i]=rdn(); for(int t=1;t<=100;t++)if(a[t]>=2) { a[t]-=2; memset(dp[1],0,sizeof dp[1]); dp[1][a[1]][a[2]][a[3]]=1; for(int i=3;i<=102;i++) { flag=0;int d=(i&1); memset(dp[!d],0,sizeof dp[!d]); for(int x=0;x<=a[i-2];x++) for(int y=0;y<=a[i-1];y++) for(int z=0;z<=a[i];z++) if(dp[d][x][y][z]) { int lm=min(x,min(y,z)); for(int k=0;k<=lm;k++) { dp[!d][y-k][z-k][a[i+1]]|=(((x-k)%3==0)|((x-k)%4==0)); if(dp[!d][y-k][z-k][a[i+1]])flag=1; } } if(!flag)break; } a[t]+=2; if(flag)break; } if(flag)printf("Yes\n");else printf("No\n"); } return 0;}
View Code

如果不枚举对子在哪而是带一个0/1在状态里的话可以少乘一个100。

如果不无脑记录前两个位置而是仅记录前一个位置、用三连的时候调用一下上一层的话可以少乘一个100。

  这是因为最后要的只有dp[ ][0][0][0],所以保存很多“之前位置还不是0”的状态比较浪费。

不枚举用了几个三连,而是每层用“从开头降到这里”更新一下本层,就能把”在本层用较少的三连“包括在“用单个位置从之前层降下来”。这样可以少乘一个100。

  这里调了好久!必须是“从开头降到这里”,而不能是“从这里降到0”;因为从“这里”降的话需要判断本层是否可行,但这个可行是包括 i-2 的状态的,自己仅记录前一个位置的dp不能存下。如果是”从开头降到这里“的话,本层目前一定是可行的。

O(100^4)卡过。

#include
#include
#include
#include
using namespace std;const int N=110;int T,a[N];bool dp[N][N][N][2];int rdn(){ int ret=0;char ch=getchar(); while(ch>'9'||ch<'0')ch=getchar(); while(ch>='0'&&ch<='9')(ret*=10)+=ch-'0',ch=getchar(); return ret;}int main(){ T=rdn(); while(T--) { memset(dp,0,sizeof dp); for(int i=1;i<=100;i++)a[i]=rdn(); dp[1][0][a[1]][0]=1; for(int i=1;i<=100;i++) { for(int x=a[i-1];x>=0;x--) for(int y=a[i];y>=0;y--) { dp[i][x][y][1]|=dp[i][x][y+2][0]; dp[i][x][y][0]|=dp[i][x][y+3][0]; dp[i][x][y][1]|=dp[i][x][y+3][1]; dp[i][x][y][0]|=dp[i][x][y+4][0]; dp[i][x][y][1]|=dp[i][x][y+4][1]; //在a[i]变成各种y之后尝试一下从开头降到这里(先降后单个弄) dp[i][x][y][0]|=dp[i-1][a[i]-y][x+a[i]-y][0]; dp[i][x][y][1]|=dp[i-1][a[i]-y][x+a[i]-y][1]; //在a[i]变成各种y之后尝试一下取完 // dp[i][x][0][0]|=dp[i-1][y][x+y][0];//不能&dp[i][x+y][y],因含义是i-2==0 // dp[i][x][0][1]|=dp[i-1][y][x+y][1];//不&的话会出错:0 3 0(原为2) //因为从当前降到0的话,需要判断当前是否可行 //可是降还需要i-2的也许有值,与表示“当前可行”的dp冲突,即无法表示当前是否可行 //而“从开头”降的话,一定可行 //x之所以不是0,是因为这里用到dp[i-1][y][][] if(!x) { dp[i+1][y][a[i+1]][0]|=dp[i][0][y][0]; dp[i+1][y][a[i+1]][1]|=dp[i][0][y][1]; }// if(i<=3)// {// if(dp[i][x][y][0])printf("dp[%d][%d][%d][%d]=%d\n",i,x,y,0,dp[i][x][y][0]);// if(dp[i][x][y][1])printf("dp[%d][%d][%d][%d]=%d\n",i,x,y,1,dp[i][x][y][1]);// } } } puts(dp[100][0][0][1]?"Yes":"No"); } return 0;}

 

转载于:https://www.cnblogs.com/Narh/p/9370833.html

你可能感兴趣的文章
Hadoop源码解析之: TextInputFormat如何处理跨split的行
查看>>
浅谈压缩感知(二十):OMP与压缩感知
查看>>
ORA-12012: error on auto execute of job &quot;ORACLE_OCM
查看>>
[转]jQuery UI Dialog Modal Popup Yes No Confirm example in ASP.Net
查看>>
通过jQuery的attr修改onclick
查看>>
DNS分别在什么情况下使用UDP和TCP
查看>>
总体参数的估计(概念)
查看>>
stl源代码剖析:编译器的提前定义位置集设置
查看>>
在软件项目管理中怎样把时间估算的靠近真实值?
查看>>
Ruby gem命令
查看>>
分析cocos2d-x在Android上的编译过程(1):cocco2d-x是怎样生成的Android的文件夹结构...
查看>>
POJ 2029 DP || 暴力
查看>>
[转] DBCP 的validationQuery
查看>>
使用VS Code开发ASP.NET Core 应用程序
查看>>
Leetcode:linked_list_cycle
查看>>
[转]实体类(VO,DO,DTO)的划分
查看>>
Qt on Android:让 Qt Widgets 和 Qt Quick 应用全屏显示
查看>>
【原创整理,基于JavaScript的创建对象方式的集锦】
查看>>
iOS边练边学--UINavigationController导航条的使用
查看>>
redmine一键安装包下载链接
查看>>