今天一共四道插头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. SpringData_03_Specifications动态查询

    有时我们在查询某个实体的时候,给定的条件是不固定的,这时就需要动态构建相应的查询语句,在Spring Data JPA中可以通过JpaSpecificationExecutor接口查询.相比JPQL, ...

  2. 深入浅出 Java Concurrency (40): 并发总结 part 4 性能与伸缩性[转]

    性能与伸缩性 使用线程的一种说法是为了提高性能.多线程可以使程序充分利用闲置的资源,提高资源的利用率,同时能够并行处理任务,提高系统的响应性. 但是很显然,引入线程的同时也引入了系统的复杂性.另外系统 ...

  3. dns 逐级查找顺序

    1.浏览器 dns 缓存 2.Windows Host 文本 3.windows 本地 dns 缓存 方法/步骤 首先我们来查看win系统内保存的dns缓存并进行清空dns缓存操作. ... 点击确定 ...

  4. js 实现页面局部(或图片)放大功能(vue)

    方法: adjustStart1 (e) { e.preventDefault() let event = e.touches if (event.length === 2) { this.style ...

  5. JavaScript事件(随笔)

    1. Javascript事件介绍 JavaScript中的事件和现实生活中的事件类似,现实生活中发生的一些事情,例如:交通事件,当这些事情发生时,我们需要提供处理方案: 在JavaScript中事件 ...

  6. Cocos2d-x发布Android.mk 导入所有cpp

    #traverse all the directory and subdirectorydefine walk $(wildcard $(1)) $(foreach e, $(wildcard $(1 ...

  7. Linux RHEL7(CentOS7源) 安装 Nginx

    安装步骤 1.添加 Nginx 源地址 CentOS7 默认没有提供 Nginx 的源,但 Nginx 自己提供了 sudo rpm -Uvh http://nginx.org/packages/ce ...

  8. Axure教程:如何使用动态面板?动态面板功能详解

    写了几个Axure教程之后发现,可能教程的起点有些高了,过分的去讲效果的实现,而忽略了axure功能以及基础元件的使用,那么从这个教程开始,把这些逐渐的展开讲解. 关于Axure动态面板 动态面板是a ...

  9. Struts2入门问题

    一 使用Struts 2 开发程序的基本步骤 加载Struts2 类库 配置web.xml文件 开发视图层页面 开发控制层Action 配置struts.xml文件 部署.运行项目 第一步先导架包:在 ...

  10. 从0开始学习ssh之岗位管理

    岗位应该有如下属性,id.名称.说明.新建role.java.添加id,name,description并增加三个的get set方法. 之后建立Role.hbm.xml 并加入到applicatio ...