插头DP智障操作合集
今天一共四道插头DP【其实都差不多】,智障错误出了不下五个:D
来,让我好好数落我自己一下
直接写代码注释里吧
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int t,n,m;
int a[][],sit[];
long long f[][][(<<)+];//忘开long long几百次
void clear(){
memset(f,,sizeof(f));
memset(a,,sizeof(a));
}
void work(int x,int y){
int plug1=sit[y-],plug2=sit[y];
for(int i=;i<sit[m+];i++){
if(a[x][y]){
f[x][y][i]+=f[x][y-][i^plug1^plug2];
if(((i>>y-)&)==((i>>y)&))continue;
f[x][y][i]+=f[x][y-][i];
}
else{
if(!(i&plug1)&&!(i&plug2))f[x][y][i]=f[x][y-][i];
else f[x][y][i]=;
}
}
}
int main()
{
scanf("%d",&t);
sit[]=;
for(int i=;i<=;i++)sit[i]=sit[i-]<<;
while(t--){
clear();
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++){
for(int j=;j<=m;j++){
scanf("%d",&a[i][j]);
}
}
f[][][]=;
for(int i=;i<=n;i++){
for(int j=;j<=m;j++){
work(i,j);
}
if(i!=n){
for(int j=;j<sit[m];j++){
f[i+][][j<<]=f[i][m][j];
}
}
}
printf("%lld\n",f[n][m][]);
}
return ;
}
//第一篇几乎是对着前辈的代码打的 大概没什么问题 【虽然本质应该是背着打然后对着改】
Ural 1519 Formula 1
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int n,m,e1,e2,las,now,tt;
const int has=;
int sit[],a[][],mp[][],head[],Next[],tot[];
long long f[][],ans;
char c[];
void ins(int zt,long long num){
int pos=zt%has+;
for(int i=head[pos];i;i=Next[i]){
if(a[now][i]==zt){
f[now][i]+=num;
return;
}
}
Next[++tot[now]]=head[pos],head[pos]=tot[now];
a[now][tot[now]]=zt,f[now][tot[now]]=num;
}
void work(){
tot[now]=,f[now][]=,a[now][]=;
for(int i=;i<=n;i++){
for(int j=;j<=tot[now];j++)a[now][j]<<=;
for(int j=;j<=m;j++){
las=now,now^=;
memset(head,,sizeof(head));
tot[now]=;
for(int k=;k<=tot[las];k++){
int zt=a[las][k],b1=((zt>>((j-)*))%),b2=((zt>>(j*))%);
long long num=f[las][k];
if(!mp[i][j]){
if(!b1&&!b2)ins(zt,num);
}
else if(!b1&&!b2){
if(mp[i+][j]&&mp[i][j+])ins(zt+sit[j-]+*sit[j],num);
}
else if(b1&&!b2){
if(mp[i][j+])ins(zt-sit[j-]*b1+sit[j]*b1,num);
if(mp[i+][j])ins(zt,num);
}
else if(!b1&&b2){
if(mp[i+][j])ins(zt-sit[j]*b2+sit[j-]*b2,num);
if(mp[i][j+])ins(zt,num);
}
else if(b1==&&b2==){
int kl=;
for(int t=j+;t<=m;t++){
if((zt>>(t*))%==)kl++;
if((zt>>(t*))%==)kl--;
if(!kl){
ins(zt-sit[j-]-sit[j]-sit[t],num);
break;
}
}
}
else if(b1==&&b2==){
int kl=;
for(int t=j-;t>;t--){
if((zt>>(t*))%==)kl--;
if((zt>>(t*))%==)kl++;
if(!kl){
ins(zt+sit[t]-*sit[j-]-*sit[j],num);
break;
}
}
}
else if(b1==&&b2==){
ins(zt-*sit[j-]-sit[j],num);
}
else if(i==e1&&j==e2)ans+=num;
}
}
}
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++){
scanf("%s",c+);
for(int j=;j<=m;j++){
if(c[j]=='.')mp[i][j]=,e1=i,e2=j;
}
}
sit[]=;
for(int i=;i<=;i++){
sit[i]=(sit[i-]<<);
}
work();
printf("%lld\n",ans);
return ;
}
//其实也是背着写了一遍再对着标程改…这一篇是一次AC【这是个伏笔】
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int m,n,now,lst;
const int has=;
int sit[],a[][],head[],Next[],tot[];
struct node{
int len;
int c[];
}f[][],ans;
node jia(node a,node b){
node d;
int sum=;
memset(d.c,,sizeof(d.c));
d.len=max(a.len,b.len);
for(int i=;i<=d.len;i++){
sum=sum+a.c[i]+b.c[i];
d.c[i]=sum%;
sum/=;
}
while(sum){
d.c[++d.len]=sum%;
sum/=;
}
return d;
}
void ins(int zt,node num){
int pos=zt%has+;
for(int i=head[pos];i;i=Next[i]){
if(a[now][i]==zt){
f[now][i]=jia(f[now][i],num);//这个地方写成了jia(f[now][i],num)
//对,不是f[now][i]=jia(f[now][i],num)…只写了调用函数没有赋值…还以为是高精炸了
return;
}
}
Next[++tot[now]]=head[pos],head[pos]=tot[now];
a[now][tot[now]]=zt,f[now][tot[now]]=num;
}
void work(){
memset(f[now][].c,,sizeof(f[now][].c));
tot[now]=,a[now][]=,f[now][].len=,f[now][].c[]=;
for(int i=;i<=n;i++){
for(int j=;j<=tot[now];j++)a[now][j]<<=;
for(int j=;j<=m;j++){
lst=now,now^=;
memset(head,,sizeof(head));
tot[now]=;
for(int k=;k<=tot[lst];k++){
node num=f[lst][k];
int zt=a[lst][k];
int b1=((zt>>(j-)*))%,b2=(zt>>(j*))%;
if(!b1&&!b2){
if(j+<=m&&i+<=n)ins(zt+sit[j-]+sit[j]*,num);
}
else if(!b1&&b2){
if(j+<=m)ins(zt,num);
if(i+<=n)ins(zt-sit[j]*b2+sit[j-]*b2,num);
}
else if(b1&&!b2){
if(i+<=n)ins(zt,num);
if(j+<=m)ins(zt-sit[j-]*b1+sit[j]*b1,num);
}
else if(b1==&&b2==){
int kl=;
for(int t=j+;t<=m;t++){
if((zt>>(t*))%==)kl++;
if((zt>>(t*))%==)kl--;
if(!kl){
ins(zt-sit[j]-sit[j-]-sit[t],num);
break;
}
}
}
else if(b1==&&b2==){
int kl=;
for(int t=j-;t>;t--){//写成j-1一万次……
if((zt>>(t*))%==)kl--;
if((zt>>(t*))%==)kl++;
if(!kl){
ins(zt-sit[j]*-sit[j-]*+sit[t],num);
break;
}
}
}
else if(b1==&&b2==){
ins(zt-sit[j-]*-sit[j],num);
}
else if(i==n&&j==m)ans=jia(ans,num);
}
}
}
}
int main()
{
scanf("%d%d",&m,&n);
if(m==||n==){//这个特判,一开始打成m==1||n==1 输出0…然后折腾了半天想路径长度去了【?】 然后写成了m==1&&n==1 输出1…
printf("");
return ;
}
sit[]=;
for(int i=;i<=;i++)sit[i]=(sit[i-]<<);//一开始跑了n的范围,20,还没意识到炸了…被提醒以后第一反应居然是开long long而不是转成m的范围
work();
ans=jia(ans,ans);
if(!ans.len){
printf("");
return ;
}
for(int i=ans.len;i>=;i--){
printf("%d",ans.c[i]);
}
return ;
}
CITY
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int n,m,now,lst,e1,e2;
const int has=;
long long ans,f[][];
int a[][],tot[],Next[],head[],sit[];
char mp[][],s[];
void ins(int zt,long long num){
int pos=zt%has+;
for(int i=head[pos];i;i=Next[i]){
if(a[now][i]==zt){
f[now][i]+=num;
return;
}
}
Next[++tot[now]]=head[pos],head[pos]=tot[now];
a[now][tot[now]]=zt,f[now][tot[now]]=num;
}
void work(){
tot[now]=,a[now][]=,f[now][]=;
for(int i=;i<=n;i++){
for(int j=;j<=tot[now];j++)a[now][j]<<=;
for(int j=;j<=m;j++){
lst=now,now^=;
memset(head,,sizeof(head));
tot[now]=;
for(int k=;k<=tot[lst];k++){
long long num=f[lst][k];
int zt=a[lst][k],b1=(zt>>((j-)*))%,b2=(zt>>(j*))%;
if(mp[i][j]=='#'){
if(!b1&&!b2)ins(zt,num);
}
else if(!b1&&!b2){
if(mp[i][j]=='.'&&(mp[i+][j]=='|'||mp[i+][j]=='.')&&(mp[i][j+]=='-'||mp[i][j+]=='.')){
ins(zt+sit[j-]+sit[j]*,num);
}
}
else if(b1&&!b2){
if((mp[i+][j]=='.'||mp[i+][j]=='|')&&mp[i][j]!='-'&&mp[i][j]!='|')ins(zt,num);
if((mp[i][j+]=='.'||mp[i][j+]=='-')&&mp[i][j]!='|')ins(zt-sit[j-]*b1+sit[j]*b1,num);
}
else if(!b1&&b2){
if((mp[i][j+]=='.'||mp[i][j+]=='-')&&mp[i][j]!='-'&&mp[i][j]!='|')ins(zt,num);
if((mp[i+][j]=='.'||mp[i+][j]=='|')&&mp[i][j]!='-')ins(zt-sit[j]*b2+sit[j-]*b2,num);
}
else if(b1==&&b2==){
if(mp[i][j]!='-'&&mp[i][j]!='|'){
int kl=;
for(int t=j+;t<=m;t++){
if((zt>>(t*))%==)kl++;
if((zt>>(t*))%==)kl--;
if(!kl){
ins(zt-sit[j]-sit[j-]-sit[t],num);
break;
}
}
}
}
else if(b1==&&b2==){
if(mp[i][j]!='-'&&mp[i][j]!='|'){
int kl=;
for(int t=j-;t>;t--){
if((zt>>(t*))%==)kl--;
if((zt>>(t*))%==)kl++;
if(!kl){
ins(zt-sit[j]*-sit[j-]*+sit[t],num);
break;
}
}
}
}
else if(b1==&&b2==){
if(mp[i][j]!='-'&&mp[i][j]!='|'){
ins(zt-sit[j-]*-sit[j],num);
}
}
else if(i==e1&&j==e2&&mp[i][j]!='-'&&mp[i][j]!='|'){//伏笔还是要收的,久等了【大雾】
// 上一道题没有用到e1e2,第二道题我又是照着标程改的,然后完美忘记,从(n,m)的地方累计答案去了
//居然还有90分,折腾了半天细节,结果是这里…
ans+=num;
}
}
}
}
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++){
scanf("%s",s+);
for(int j=;j<=m;j++){
mp[i][j]=s[j];
if(j==||j==m){
if(mp[i][j]=='-'){
printf("");
return ;
}
}
if(i==||i==n){
if(mp[i][j]=='|'){
printf("");
return ;
}
}
if(mp[i][j]!='#')e1=i,e2=j;//伏 笔 回 收 ,欠下的总是要还的
}
}
sit[]=;
for(int i=;i<=;i++)sit[i]=sit[i-]<<;
work();
printf("%lld",ans);
return ;
}
今天也在非常认真地怀疑自己的智商
插头DP智障操作合集的更多相关文章
- SQL用法操作合集
SQL用法操作合集 一.表的创建 1.创建表 格式: 1 CREATE TABLE 表名 2 (列名 数据类型(宽度)[DEFAULT 表达式][COLUMN CONSTRAINT], 3 ... ...
- DP+贪心水题合集_C++
本文含有原创题,涉及版权利益问题,严禁转载,违者追究法律责任 本次是最后一篇免费的考试题解,以后的考试题目以及题解将会以付费的方式阅读,题目质量可以拿本次作为参考 本来半个月前就已经搞得差不多了,然后 ...
- javascript 最全面的数组操作合集
一.数组添加.删除.替换.截取操作 1.arr.unshift(1) 在数组头部添加一个元素 1 (直接改变原数组,返回值为添加元素后数组的length) 2.arr.shift() 在数组的头部删除 ...
- Java文件复制删除操作合集
import java.io.*; public class FileOperate { public FileOperate() { } /** * 新建目录 * @param folderPath ...
- git操作合集
目录 安装 下载 本地配置 创建用户凭证ssh 忽略文件 基础操作 新建仓库 克隆仓库 获取更新 推送更新 查看历史 版本回退 分支 别名 linux服务器 疑难问题 清除历史大文件 安装 下载 下载 ...
- git常用操作合集
基本操作git status 查看文件处于什么状态 git status -s 带上-s参数,可以以更紧凑的格式输出文件状态信息 git add 开始追踪该文件或者暂存已修改的文件. .gitigno ...
- HTMLCollection 对象详解,以及为什么循环获取的dom合集操作可能会出现下标不正确的情况?
有时候循环dom合集,然后操作其中的某些dom之后,发现下标不正确了 比如我们要删除一个dom合集的时候: var selectDom = document.getElementsByClassNam ...
- python字符串操作实方法大合集
python字符串操作实方法大合集,包括了几乎所有常用的python字符串操作,如字符串的替换.删除.截取.复制.连接.比较.查找.分割等,需要的朋友可以参考下: #1.去空格及特殊符号 s.st ...
- 【转】Reflector、reflexil、De4Dot、IL相关操作指令合集
PS:CTRL+F 输入你需要的内容,可以快速查找页面上的内容. 名称 说明 Add 将两个值相加并将结果推送到计算堆栈上. Add.Ovf 将两个整数相加,执行溢出检查,并且将结果推送到计算堆栈上. ...
随机推荐
- slam课程
美国宾夕法尼亚大学最近有录制一套 无人机视觉定位导航相关的视频课程,2019年3月份在YouTube上更新完毕,质量非常高,名字叫Robotics,视频课程列表:https://www.youtube ...
- shell学习笔记1: shell 中的变量与常见符号使用方法
变量 声明即用 a=2 b="123" 调用 ${varName}或者 $varName echo $b echo ${a} 常见变量 $?:判断上一个语句是否成功 $0:执行脚本 ...
- 【solr】Solr与JDK对应版本关系,Tomcat与JDK
Solr与JDK对应版本关系,Tomcat与JDK版本对应关系 最新在部署solrCloud集群,由于自己机器上用的JDK都是JDK1.7的,然后我就从网上下载了最新下载了最先的solr6.6.0和最 ...
- codeforces 1195D2-Submarine in the Rybinsk Sea
传送门:QAQQAQ 题意:自己看 思路:就是一个类似于数位DP的东西... 统计a[i]数位分解的数在每一位出现的个数,即分两种讨论: 1.位数小于当前j,则j会出现在q+i,而且计算顺序互换会计算 ...
- day71test
目录 练习: settings.py views.py: exception.py urls.py 练习: 视图类渲染,解析, 异常配置: 作业: 1..简单过过请求模块的源码流程,建立一个视图类,完 ...
- Mysql 增加rownum
Mysql 增加rownum 实现(极度推荐) mysql本身不像oracle那样使用 rownum 来显示行号的功能.但是可以使用设置变量的方式来实现这一功能. mysql使用 @ 定义用户变量, ...
- 深度残差网络——ResNet学习笔记
深度残差网络—ResNet总结 写于:2019.03.15—大连理工大学 论文名称:Deep Residual Learning for Image Recognition 作者:微软亚洲研究院的何凯 ...
- [转]WPF自定义控件之带倒计时的按钮--Button
1.说明 之前做过一个小项目,点击按钮,按钮进入倒计时无效状态,计时完成后,恢复原样,现在就实现该效果---带倒计时的按钮 2.效果 1)正常状态 2)MouseOver( ...
- 廖雪峰Java11多线程编程-1线程的概念-3线程的状态
1线程的状态 线程终止的的原因: run()或call()方法执行完成,线程正常结束 线程抛出一个未捕获的Exception或Error 直接调用该线程的stop()方法来结束该线程--该方法容易导致 ...
- poj 2288
传送门 解题思路 状压dp,记录路径条数,dp[S][i][j]表示状态为S,前一个点是i,再前一个点是j的最大值,然后在开个一样的数组记录方案数,时间复杂度O(2^n*n^2),注意要用long l ...