今天一共四道插头DP【其实都差不多】,智障错误出了不下五个:D

来,让我好好数落我自己一下

直接写代码注释里吧

Eat the Trees

#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【这是个伏笔】

P2289 [HNOI2004]邮递员

#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智障操作合集的更多相关文章

  1. SQL用法操作合集

    SQL用法操作合集   一.表的创建 1.创建表 格式: 1 CREATE TABLE 表名 2 (列名 数据类型(宽度)[DEFAULT 表达式][COLUMN CONSTRAINT], 3 ... ...

  2. DP+贪心水题合集_C++

    本文含有原创题,涉及版权利益问题,严禁转载,违者追究法律责任 本次是最后一篇免费的考试题解,以后的考试题目以及题解将会以付费的方式阅读,题目质量可以拿本次作为参考 本来半个月前就已经搞得差不多了,然后 ...

  3. javascript 最全面的数组操作合集

    一.数组添加.删除.替换.截取操作 1.arr.unshift(1) 在数组头部添加一个元素 1 (直接改变原数组,返回值为添加元素后数组的length) 2.arr.shift() 在数组的头部删除 ...

  4. Java文件复制删除操作合集

    import java.io.*; public class FileOperate { public FileOperate() { } /** * 新建目录 * @param folderPath ...

  5. git操作合集

    目录 安装 下载 本地配置 创建用户凭证ssh 忽略文件 基础操作 新建仓库 克隆仓库 获取更新 推送更新 查看历史 版本回退 分支 别名 linux服务器 疑难问题 清除历史大文件 安装 下载 下载 ...

  6. git常用操作合集

    基本操作git status 查看文件处于什么状态 git status -s 带上-s参数,可以以更紧凑的格式输出文件状态信息 git add 开始追踪该文件或者暂存已修改的文件. .gitigno ...

  7. HTMLCollection 对象详解,以及为什么循环获取的dom合集操作可能会出现下标不正确的情况?

    有时候循环dom合集,然后操作其中的某些dom之后,发现下标不正确了 比如我们要删除一个dom合集的时候: var selectDom = document.getElementsByClassNam ...

  8. python字符串操作实方法大合集

    python字符串操作实方法大合集,包括了几乎所有常用的python字符串操作,如字符串的替换.删除.截取.复制.连接.比较.查找.分割等,需要的朋友可以参考下:   #1.去空格及特殊符号 s.st ...

  9. 【转】Reflector、reflexil、De4Dot、IL相关操作指令合集

    PS:CTRL+F 输入你需要的内容,可以快速查找页面上的内容. 名称 说明 Add 将两个值相加并将结果推送到计算堆栈上. Add.Ovf 将两个整数相加,执行溢出检查,并且将结果推送到计算堆栈上. ...

随机推荐

  1. slam课程

    美国宾夕法尼亚大学最近有录制一套 无人机视觉定位导航相关的视频课程,2019年3月份在YouTube上更新完毕,质量非常高,名字叫Robotics,视频课程列表:https://www.youtube ...

  2. shell学习笔记1: shell 中的变量与常见符号使用方法

    变量 声明即用 a=2 b="123" 调用 ${varName}或者 $varName echo $b echo ${a} 常见变量 $?:判断上一个语句是否成功 $0:执行脚本 ...

  3. 【solr】Solr与JDK对应版本关系,Tomcat与JDK

    Solr与JDK对应版本关系,Tomcat与JDK版本对应关系 最新在部署solrCloud集群,由于自己机器上用的JDK都是JDK1.7的,然后我就从网上下载了最新下载了最先的solr6.6.0和最 ...

  4. codeforces 1195D2-Submarine in the Rybinsk Sea

    传送门:QAQQAQ 题意:自己看 思路:就是一个类似于数位DP的东西... 统计a[i]数位分解的数在每一位出现的个数,即分两种讨论: 1.位数小于当前j,则j会出现在q+i,而且计算顺序互换会计算 ...

  5. day71test

    目录 练习: settings.py views.py: exception.py urls.py 练习: 视图类渲染,解析, 异常配置: 作业: 1..简单过过请求模块的源码流程,建立一个视图类,完 ...

  6. Mysql 增加rownum

    Mysql 增加rownum 实现(极度推荐) mysql本身不像oracle那样使用 rownum 来显示行号的功能.但是可以使用设置变量的方式来实现这一功能. mysql使用 @ 定义用户变量, ...

  7. 深度残差网络——ResNet学习笔记

    深度残差网络—ResNet总结 写于:2019.03.15—大连理工大学 论文名称:Deep Residual Learning for Image Recognition 作者:微软亚洲研究院的何凯 ...

  8. [转]WPF自定义控件之带倒计时的按钮--Button

    1.说明 之前做过一个小项目,点击按钮,按钮进入倒计时无效状态,计时完成后,恢复原样,现在就实现该效果---带倒计时的按钮 2.效果 1)正常状态               2)MouseOver( ...

  9. 廖雪峰Java11多线程编程-1线程的概念-3线程的状态

    1线程的状态 线程终止的的原因: run()或call()方法执行完成,线程正常结束 线程抛出一个未捕获的Exception或Error 直接调用该线程的stop()方法来结束该线程--该方法容易导致 ...

  10. poj 2288

    传送门 解题思路 状压dp,记录路径条数,dp[S][i][j]表示状态为S,前一个点是i,再前一个点是j的最大值,然后在开个一样的数组记录方案数,时间复杂度O(2^n*n^2),注意要用long l ...