POJ 1185(在求最大炮数上,输出一条方案,未Accept,网站在维护)

一,状态压缩不讲了,很简单的;

二,讲讲最核心的算法,怎么算过来的;

a, 首先,动态规划是在求出子问题的基础上,并子问题不能变,在这个基础上,慢慢向后推,求出最终问题;

b, 难点就在这里,子问题是改变的,在这一行的数受到上一行和上上一行的影响,是改变的;

c, 但是在推到第3行时,表示第3行的状态时,包括第前2行,一起算到第3行,这样,在求第4行时,只需要看第4行的状态(包括第4行的前2行)的所用状态;

第3行的第一种状态的后二个状态数,与第4行的一种状态的前二个状态数匹配,成,就加上第4行的后一个状态数的炮的数量,进行求最大炮的数量;依次类推;

算完后,只要将最后一行的所有状态的炮的数量输出就好了;

三,我输出路径的方法;

每走一流程,到下一步,下一步,就会记录这一步的的位置;

这样,只要最后的位置,就可以反向推出一种方案;

#include <iostream>
#include <stdio.h>
#include <cstring>
using namespace std;
const int N = 101;
const int M = 10;
int m,n;
int maze[N];
char arg[N][M];
int mazeAloneState[N][60];
int mazeAllState[N][216000][5];
int result,finish;
int minA,minB,minC;
int getNumber(int num){
	int count=0; 
	int i;
	for(i=0; i<m; i++){
		if(num&(1<<i))
			count++;
	}
	return count;
}
int getSum(int n){
	if(n==0)  return 0;
	if(n>=59) return 4;
	if(n>=38) return 3;
	if(n>=11) return 2;
	if(n>=1)  return 1;
}
void showAll(int local){
	int i=0;
	if(local < 2) return;
	printf("*****************\n");
	while(mazeAllState[local][i][0] != -1){
		printf("%6d %6d %6d %6d %6d\n",
		mazeAllState[local][i][0], mazeAllState[local][i][1], mazeAllState[local][i][2], mazeAllState[local][i][3],
		mazeAllState[local][i][4] );
		i++;	
	}
	printf("*****************");
}
void subA(){
	int i,j,k,max,temp,min;
	max = 0;
	for(i=59; i>=0; i--){
		if(mazeAloneState[0][i] != -1){
			
			temp = getSum(i);
			if(max<=temp){			
				max = temp;
				minA = i;
			}			
		}		
	}	
	result = max;
}
void subB(){	
	int i,j,max=0,temp;
	for(i=59; i>=0; i--){
		for(j=59; j>=0; j--){
			if(mazeAloneState[0][i]==-1 || mazeAloneState[1][j] == -1)
				continue;
			if( !( mazeAloneState[0][i] & mazeAloneState[1][j] ) ){					
				temp = getSum(i) + getSum(j);
				if(max<=temp ){
					max = temp;
					minA=i;
					minB=j;
				}
			}			
		}
	}
	result = max;	
}
void subC(){
	int i,j,k,max=0,temp,count = 0;
	for(i=59; i>=0; i--){
		for(j=59; j>=0; j--){
			for(k=59; k>=0; k--){
				if(mazeAloneState[0][i] == -1 || mazeAloneState[1][j] == -1 || mazeAloneState[2][k] == -1)
					continue;
				if(  !(mazeAloneState[0][i]&mazeAloneState[1][j])   &&  !(mazeAloneState[0][i]&mazeAloneState[2][k])
					&&	!(mazeAloneState[2][k]&mazeAloneState[1][j]) ) {						
						temp = getSum(i) + getSum(j) + getSum(k);
						mazeAllState[2][count][0] = mazeAloneState[0][i];
						mazeAllState[2][count][1] = mazeAloneState[1][j];
						mazeAllState[2][count][2] = mazeAloneState[2][k];
						mazeAllState[2][count][3] = temp;
						mazeAllState[2][count][4] = 0;
						count++;
						if(max<=temp){
							max=temp;
							minA=i;
							minB=j;
							minC=k;
						}
				}
			}
		}
	}
	result = max;
}
void solveAll(){
	if(n<4) return ;
	int number = 3;
	while(number < n){
		
			int i,j,k,minA,minB,minC,max=0,temp,count = 0;
			for(i=59; i>=0; i--){
				for(j=59; j>=0; j--){
					for(k=59; k>=0; k--){
						if(mazeAloneState[number-2][i] == -1 || mazeAloneState[number-1][j] == -1 || mazeAloneState[number][k] == -1)
							continue;
						if(  !(mazeAloneState[number-2][i]&mazeAloneState[number-1][j])   &&  !(mazeAloneState[number-2][i]&mazeAloneState[number][k])
							&&	!(mazeAloneState[number][k]&mazeAloneState[number-1][j]) ) {						
								temp = getSum(k);
								mazeAllState[number][count][0] = mazeAloneState[number-2][i];								
								mazeAllState[number][count][1] = mazeAloneState[number-1][j];
								mazeAllState[number][count][2] = mazeAloneState[number][k];
								mazeAllState[number][count][3] = temp;
								mazeAllState[number][count][4] = 0;
								count++;
								if(max<=temp){
									max=temp;									
								}
						}
					}
				}
			}
			number++;
	}
	
			
}
void getNext(int next[], int m){	
	int i,j;
	for(i=m-1,j=0; i>=0; i-- ){
		next[j++] = 1<<i;		
	}
}
void init(int n, int m){
	memset(maze, 0, sizeof(int)*N);
	memset(mazeAloneState, -1, sizeof(int)*N*60);
	memset(mazeAllState, -1, sizeof(int)*N*216000*5);
	int i,j,flag,temp;
	char ch;
	int *next = new int[m];
	getNext(next, m);
	
	for(i=0; i<n; i++){		
		for(j=0; j<m; j++){
			cin>>ch;
			arg[i][j] = ch;	
			if(ch == 'H')
				maze[i]	 += next[j];			
		}
	}	

	//初始化一行的状态 
	int count=0,a,b,c,h,k;	
	for(i=0; i<n; i++){
		mazeAloneState[i][0] = 0;
		count=1;
		for(j=0; j<m; j++){
			temp = 1<<j;
			if( !(temp&maze[i]) )
				mazeAloneState[i][count++] = temp; 			
		}
		count=11;
		for(j=0; j<m; j++){
			for(k=j+3; k<m; k++){
				a = 1<<j; b = 1<<k;
				temp = a + b;							
				if( !(temp&maze[i]) )
					mazeAloneState[i][count++] = temp;
			}
		}
		count=39;
		for(j=0; j<m; j++){
			for(k=j+3; k<m; k++){
				for(h=k+3; h<m; h++){
					a=1<<j; b=1<<k; c=1<<h;
					temp = a + b + c;					
					if( !(temp&maze[i]) )
						mazeAloneState[i][count++] = temp;
				}
			}
		}
		count=59;		
		if( !(585&maze[i]) && m==10){
			mazeAloneState[i][count] = 585;
		}
	
	}
	solveAll();
}
void solve(){
	
	int i,j,k,count,temp,a,b,c,e,f;
	if(n==0){result = 0; return;}
	if(n==1){subA(); return;}
	if(n==2){subB(); return;}	
	if(n>=3){
		subC();			
		for(i=3; mazeAloneState[i][0] != -1; i++ ){			
			for(j=0; mazeAllState[i][j][0] != -1; j++){
				for(k=0; mazeAllState[i-1][k][0] != -1; k++){
					a = mazeAllState[i][j][0];
					b = mazeAllState[i][j][1];
					c = mazeAllState[i][j][2];
					temp = getNumber(c);					
					e = mazeAllState[i-1][k][1];
					f = mazeAllState[i-1][k][2];
					if(a==e && b==f)
						if(mazeAllState[i-1][k][3]+temp > mazeAllState[i][j][3]){
							mazeAllState[i][j][3] = mazeAllState[i-1][k][3]+temp;
							mazeAllState[i][j][4] = k;	
						}								
				}
			}
		}
	}	
	//找到最大值;
	int max = 0;
	for(i=0; mazeAllState[n-1][i][3] != -1; i++){	
		if( mazeAllState[n-1][i][3]>max ){
			max = mazeAllState[n-1][i][3];
			finish = i;
		}			
	}
	result = max;	
}
void inputPath(){
	printf("\n***** 倒序 ******\n");
	if(n==1) {
		printf("path = %d\n",mazeAloneState[0][minA]);
		return ;
	}
	if(n==2){		
		printf("path = %d\n",mazeAloneState[1][minB]);
		printf("path = %d\n",mazeAloneState[0][minA]);
		return ;
	}
	if(n==3){
		printf("path = %d\n",mazeAloneState[2][minC]);
		printf("path = %d\n",mazeAloneState[1][minB]);
		printf("path = %d\n",mazeAloneState[0][minA]);
		return ;
	}
	
	
	int i,j,k,temp;
	for(i=n-1; i>=3; i--){
		printf("path = %d\n",mazeAllState[i][finish][2]);
		finish = mazeAllState[i][finish][4];
	}
	printf("path = %d\n",mazeAllState[i][finish][2]);
	printf("path = %d\n",mazeAllState[i][finish][1]);	
	printf("path = %d\n",mazeAllState[i][finish][0]);	
}
int main()
{	
	cin>>n>>m;
	init(n,m);
	solve();
	printf("result = %d\n",result);
	inputPath();
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值