关于本题的DP方法
查看原帖
关于本题的DP方法
755096
2023wangzhaolan楼主2023/7/17 16:10

这题不能用DP,但是为啥我这样是AC的?有哪位大佬可以解释一下吗?

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=11,M=105;
int n,m;
int a[M][3];//a[i][0]为关灯操作,用&改变;a[i][1]为开灯操作,用|改变
int f[1<<N];
signed main(){
	cin>>n>>m;
	for(int i=1;i<=m;i++){
		for(int j=1;j<=n;j++){
			int x;cin>>x;
			if(x==1){
				a[i][0]=a[i][0]|1<<(j-1);
			}
			if(x==-1){
				a[i][1]=a[i][1]|1<<(j-1);
			}
		}
		a[i][0]=~a[i][0];
	}
	memset(f,1145141919810ll,sizeof f);
	f[(1<<n)-1]=0;
	for(int tt=1;tt<=m;tt++){
	    for(int s=(1<<n)-1;s;s--){
    		for(int i=1;i<=m;i++){
    			int k=s;
    			k=k|a[i][1];
    			k=k&a[i][0];
    			f[k]=min(f[k],f[s]+1);
    		}
    	}
	}
	
	if(f[0]<=1145141919810ll)cout<<f[0]<<endl;
	else cout<<-1<<endl;
	return 0;
}

而且在我减去一层循环,也就是一下这个样子后,会被hack数据hack掉一个点:

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=11,M=105;
int n,m;
int a[M][3];//a[i][0]为关灯操作,用&改变;a[i][1]为开灯操作,用|改变
int f[1<<N];
signed main(){
	cin>>n>>m;
	for(int i=1;i<=m;i++){
		for(int j=1;j<=n;j++){
			int x;cin>>x;
			if(x==1){
				a[i][0]=a[i][0]|1<<(j-1);
			}
			if(x==-1){
				a[i][1]=a[i][1]|1<<(j-1);
			}
		}
		a[i][0]=~a[i][0];
	}
	memset(f,1145141919810ll,sizeof f);
	f[(1<<n)-1]=0;
	for(int s=(1<<n)-1;s;s--){
    for(int i=1;i<=m;i++){
    	int k=s;
    	k=k|a[i][1];
    	k=k&a[i][0];
    	f[k]=min(f[k],f[s]+1);
   	 }
   }
	
	
	if(f[0]<=1145141919810ll)cout<<f[0]<<endl;
	else cout<<-1<<endl;
	return 0;
}
2023/7/17 16:10
加载中...