• 第七天 dfs剪枝&优化


    第七天 dfs剪枝&优化

    1可行性剪枝
    2最优性剪枝
    3重复性剪枝


    1
    在这里插入图片描述
    输入
    5 5 6
    …S.
    XX.X.
    …X…
    …D.X
    …X…
    输出
    YES

    ——————————————

    题解

    #include
    #include
    using namespace std;
    const int N = 10;
    int n,m,T;
    char mat[N][N];
    bool vis[N][N];
    int dx[4] = {0,0,-1,1};
    int dy[4] = {1,-1,0,0};
    bool ok;
    void dfs(int x,int y,int t){
    	if(ok){
    		return;
    	}
    	if(t == T){
    		if(mat[x][y] == 'D'){
    			ok = true;
    		}
    		return;
    	}
    	vis[x][y] = true;
    	for(int i = 0;i<4;i++){
    		int tx = x + dx[i];
    		int ty = y + dy[i];
    		if(tx<0 || tx >=n || ty<0 || ty>=m || mat[tx][ty] == 'X'|| vis[tx][ty]){
    			continue;
    		}
    		dfs(tx,ty,t+1);
    	}
    	vis[x][y] = false;
    }
    int main(){
    	cin >>n>>m>>T;
    	for(int i = 0;i<n;i++){
    		cin >>mat[i];
    	}
    	int sx,sy,ex,ey;
    	for(int i = 0;i<n;i++){
    		for(int j = 0;j<m;j++){
    			if(mat[i][j] == 'S'){
    				sx = i;
    				sy = j;
    			}
    			if(mat[i][j] == 'D'){
    				ex = i;
    				ey = j;
    			}
    		}
    	}
    	if((sx+sy+ex+ey+T) % 2 != 0){
    		cout <<"NO"<<endl;
    	}else{
    		ok = false;
    		dfs(sx,sy,0);
    		if(ok){
    			cout <<"YES"<<endl;
    		}else{
    			cout <<"NO"<<endl;
    		}
    	}
    	return 0;
    } 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62

    2
    7月17日是Mr.W的生日,ACM-THU为此要制作一个体积为N*pi的M层生日蛋糕,每层都是一个圆柱体。

    设从下往上数第i(1 <= i <= M)层蛋糕是半径为Ri, 高度为Hi的圆柱。当i < M时,要求Ri > Ri+1且Hi > Hi+1。
    由于要在蛋糕上抹奶油,为尽可能节约经费,我们希望蛋糕外表面(最下一层的下底面除外)的面积Q最小。
    令Q = S*pi
    请编程对给出的N和M,找出蛋糕的制作方案(适当的Ri和Hi的值),使S最小。
    (除Q外,以上所有数据皆为正整数)

    Input:

    有两行,第一行为N(N <= 10000),表示待制作的蛋糕的体积为Nπ;第二行为M(M <= 20),表示蛋糕的层数为M。

    Output:

    仅一行,是一个正整数S(若无解则S = 0)。

    Time Limit:1000MS Memory Limit: 10000K

    Sample Input

    100
    2
    样例输出
    68
    ————————————————————————

    题解

    #include
    #include
    #include
    using namespace std;
    const int INF = 0x3f3f3f3f;
    int n,m;
    int ans;
    int vs[20];
    void dfs(int u,int v,int s,int r0,int h0){  //当前层数 当前体积 当前表面积 半径上界 高上界 
    	if(u == m){
    		if(v == n){
    			ans = min(ans,s);
    		}
    		return;
    	}
    	if(va[m-u]+v>n){
    		return;
    	}
    	if(2.0*(n-v)/r0 +s >ans){
    		return;
    	}
    	for(int r = r0;r>=m-u;r--){
    		for(int h = h0;h>=m-u;h--){
    			int tv = v+r*r*h;
    			if(tv > n)
    				continue;
    			int ts = s+2*r*h;
    			if(u == 0){
    				ts += r*r;
    			}
    			dfs(u+1,tv,ts,r-1,h-1);
    		}
    	}
    	 
    }
    int main(){
    	cin >>n>>m;
    	for(int i = 1;i<=m;i++){
    		va[i] = va[i-1]+i*i*i;
    	}
    	int r0 = sqrt(n) + 0.5;
    	ans = INF;
    	dfs(0,0,0,r0,n);
    	if(ans == INF){
    		ans = 0;
    	}
    	cout <<ans<<endl;
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49

    3
    全排列
    在这里插入图片描述

    题解

    #include
    #include
    using namespace std;
    int ans,n;
    bool vis[50];
    void dfs(int cnt,int num){ //列举的第几个数字 输出的数 
    	if(cnt == n){
    		cout <<num<<endl;
    		return;
    	}
    	for(int i = 1;i<=n;i++){
    		if(!vis[i]){
    			vis[i] = true;
    			dfs(cnt+1,num*10+i);
    			vis[i] = false;
    		}
    	}
    }
    int main(){
    	cin >>n;
    	ans = 1;
    	for(int i = 1;i<=n;i++){
    		ans *= i;
    	}
    	cout <<ans<<endl;
    	dfs(0,0);
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
  • 相关阅读:
    学习MongoTemplate操作MongoDB增删改查
    【ARM AMBA AXI 入门 13 -- AXI 协议中 RRESP 信号详细介绍】
    vue3基础
    【异常检测】【PaDiM】论文简单梳理与代码实现
    fragment如何获取activity的点击事件
    [ACM独立出版] 2024年虚拟现实、图像和信号处理国际学术会议(VRISP 2024,8月2日-4)
    前端包管理器的简介,pnpm的使用以及和npm的区别
    java计算机毕业设计特色农产品供需销售系统源程序+mysql+系统+lw文档+远程调试
    S-Clustr(影子集群)僵尸网络@Мартин.
    java时间格式化
  • 原文地址:https://blog.csdn.net/lihao1875699404/article/details/107464415