本题的搜索剪枝
  • 板块SP33 TRIP - Trip
  • 楼主lanretE
  • 当前回复3
  • 已保存回复3
  • 发布时间2023/12/23 16:01
  • 上次更新2023/12/23 18:34:06
查看原帖
本题的搜索剪枝
398190
lanretE楼主2023/12/23 16:01

这是一份能过的代码

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<string>
#include<cstring>
#include<vector>
#include<map>
#define N 85
using namespace std;
int n,m,f[N][N],pre[N][N];
char a[N],b[N];
vector<string>ans;
map<string,int>mp2;//去重最后答案的map
map<pair<string,int>,int>mp;//剪枝用的map
void get(int x,int y,string s){
    if(mp.count({s,x*100+y}))return;
    mp[{s,x*100+y}]=1;//我这里将坐标也压缩了qwq
    if(!x||!y){
        if(mp2.count(s))return;
        mp2[s]=1;ans.push_back(s);return;
    }//设当前为(x,y)
    if(pre[x][y]&1)get(x-1,y,s);//1表示可以从(x,y-1)转移
    if(pre[x][y]&2)get(x,y-1,s);//2表示可以从(x-1,y)转移
    if(pre[x][y]&4)get(x-1,y-1,a[x]+s);//4表示可以从(x-1,y-1)转移
}
int main(){
    scanf("%s%s",a+1,b+1);
    n=strlen(a+1);m=strlen(b+1);
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            //f是用于求lcs的数组,pre表示可以被转移的状态,压缩方式如上。
            f[i][j]=f[i-1][j],pre[i][j]^=1;
            if(f[i][j]<f[i][j-1])f[i][j]=f[i][j-1],pre[i][j]=2;
            else if(f[i][j]==f[i][j-1])pre[i][j]=3;
            if(a[i]==b[j]){
                if(f[i][j]<f[i-1][j-1]+1)f[i][j]=f[i-1][j-1]+1,pre[i][j]=4;
                else if(f[i][j]==f[i-1][j-1]+1)pre[i][j]^=4;
            }
        }
    }
    get(n,m,"");
    sort(ans.begin(),ans.end());
    for(int i=0;i<ans.size();i++)cout<<ans[i]<<endl;
    return 0;
}

但是如果我不在搜索剪枝的 map 里面放 pair,改成 struct 的话就会出问题,样例过不了,为啥啊

struct node{
	int a,b;
	string str;
	bool operator <(const node &q)const{
		return a<q.a;
	}
};
map<node,bool>mp;//剪枝用的map
void get(int x,int y,string s){
    node p={x,y,s};
    if(mp[p]){
		return ;
	} 
    mp[p]=1;
    if(x==0 || y==0){
    	ans.push_back(s);
    	return ;
	}
    if(f[x-1][y]==f[x][y])get(x-1,y,s);
    if(f[x][y-1]==f[x][y])get(x,y-1,s);
    if(a[x]==b[y] && f[x-1][y-1]+1==f[x][y])get(x-1,y-1,a[x]+s);
}

别的地方都一样

2023/12/23 16:01
加载中...