読者です 読者をやめる 読者になる 読者になる

AOJ 0508,0548,0581

ようやくVolume 5が全部埋まりました。まだ増えるだろうけど、せいぜい8個。

0508
枝かりゲーだと思っていたら枝かりの必要すらなかった。

#include<stdio.h>
#include<vector>
#include<algorithm>
using namespace std;
vector<int>g[100];
int used[100];
int solve(int a){
	used[a]=1;
	int ret=1;
	for(int i=0;i<g[a].size();i++){
		if(!used[g[a][i]]){
			ret=max(ret,1+solve(g[a][i]));
		}
	}
	used[a]=0;
	return ret;
}
int main(){
	int a;
	while(scanf("%d",&a),a){
		for(int i=0;i<100;i++)g[i].clear();
		for(int i=0;i<a;i++){
			int b,c;
			scanf("%d%d",&b,&c);
			b--;c--;
			g[b].push_back(c);
			g[c].push_back(b);
		}
		int ret=0;
		for(int i=0;i<100;i++)ret=max(ret,solve(i));
		printf("%d\n",ret);
	}
}

0548
逆から探索すると速い。これも枝かりいらなかった。

#include<stdio.h>
#include<algorithm>
using namespace std;
int m[10][10];
int R;
int C;
int a,b;
int dx[]={1,0,-1,0};
int dy[]={0,1,0,-1};
int solve(int s,int t,int u){
	if(u==0){
		if(s==R||t==C)return 1;
		else return 0;
	}
	int ret=0;
	for(int i=0;i<4;i++){
		int row=s;
		int col=t;
		while(1){
			row+=dx[i];
			col+=dy[i];
			if(row<0||col<0||row>=a||col>=b)break;
			if(m[row][col]==1){
				m[row][col]=3;
				ret+=solve(row,col,u-1);
				m[row][col]=1;
				break;
			}
		}
	}
	return ret;
}
int main(){
	while(scanf("%d%d",&b,&a),a){
		int c=0;
		for(int i=0;i<a;i++)
			for(int j=0;j<b;j++){
				scanf("%d",&m[i][j]);
				if(m[i][j]==1)c++;
				if(m[i][j]==2){R=i;C=j;}
			}
		printf("%d\n",solve(R,C,c));
	}
}

0581
のDP。配列の次元だけ増えるつまらない問題。

#include<stdio.h>
#include<algorithm>
using namespace std;
int dp[50][50][1<<12][4];
char str[50][51];
int dx[]={1,0,-1,0};
int dy[]={0,1,0,-1};
int main(){
	int a,b,c;
	scanf("%d%d%d",&a,&b,&c);
	for(int i=0;i<a;i++)scanf("%s",str[i]);
	for(int i=0;i<a;i++)
		for(int j=0;j<b;j++)
			if(str[i][j]=='.')str[i][j]='0';
	for(int i=0;i<a;i++)
		for(int j=0;j<b;j++)
			for(int k=0;k<(1<<12);k++)
				for(int l=0;l<4;l++)
					dp[i][j][k][l]=-99999999;
	dp[0][0][0][c]=0;
	for(int i=c;i>=0;i--){
		for(int j=0;j<a;j++){
			for(int k=0;k<b;k++){
				for(int l=0;l<(1<<12);l++){
					if(dp[j][k][l][i]<0)continue;
					int R;
					int W;
					bool ok;
					if(j<a-1&&str[j+1][k]!='#'){
						R=0;W=0;ok=true;
						for(int m=0;m<6;m++){
							R-=dx[(l>>(m*2))&3];
							W-=dy[(l>>(m*2))&3];
							if(R==1&&W==0)ok=false;
						}
						if(ok){
							dp[j+1][k][(l<<2)&((1<<12)-1)][i]=max(dp[j][k][l][i]+str[j+1][k]-'0',dp[j+1][k][(l<<2)&((1<<12)-1)][i]);
						}else{
							dp[j+1][k][(l<<2)&((1<<12)-1)][i]=max(dp[j][k][l][i],dp[j+1][k][(l<<2)&((1<<12)-1)][i]);
						}
					}
					if(k<b-1&&str[j][k+1]!='#'){
						R=0;W=0;ok=true;
						for(int m=0;m<6;m++){
							R-=dx[(l>>(m*2))&3];
							W-=dy[(l>>(m*2))&3];
							if(R==0&&W==1)ok=false;
						}
						if(ok){
							dp[j][k+1][((l<<2)+1)&((1<<12)-1)][i]=max(dp[j][k][l][i]+str[j][k+1]-'0',dp[j][k+1][((l<<2)+1)&((1<<12)-1)][i]);
						}else{
							dp[j][k+1][((l<<2)+1)&((1<<12)-1)][i]=max(dp[j][k][l][i],dp[j][k+1][((l<<2)+1)&((1<<12)-1)][i]);
						}
					}
					if(j&&str[j-1][k]!='#'&&i){
						R=0;W=0;ok=true;
						for(int m=0;m<6;m++){
							R-=dx[(l>>(m*2))&3];
							W-=dy[(l>>(m*2))&3];
							if(R==-1&&W==0)ok=false;
						}
						if(ok){
							dp[j-1][k][((l<<2)+2)&((1<<12)-1)][i-1]=max(dp[j][k][l][i]+str[j-1][k]-'0',dp[j-1][k][((l<<2)+2)&((1<<12)-1)][i-1]);
						}else{
							dp[j-1][k][((l<<2)+2)&((1<<12)-1)][i-1]=max(dp[j][k][l][i],dp[j-1][k][((l<<2)+2)&((1<<12)-1)][i-1]);
						}
					}
					if(k&&str[j][k-1]!='#'&&i){
						R=0;W=0;ok=true;
						for(int m=0;m<6;m++){
							R-=dx[(l>>(m*2))&3];
							W-=dy[(l>>(m*2))&3];
							if(R==0&&W==-1)ok=false;
						}
						if(ok){
							dp[j][k-1][((l<<2)+3)&((1<<12)-1)][i-1]=max(dp[j][k][l][i]+str[j][k-1]-'0',dp[j][k-1][((l<<2)+3)&((1<<12)-1)][i-1]);
						}else{
							dp[j][k-1][((l<<2)+3)&((1<<12)-1)][i-1]=max(dp[j][k][l][i],dp[j][k-1][((l<<2)+3)&((1<<12)-1)][i-1]);
						}
					}
				}
			}
		}
	}
	int ret=0;
	for(int i=0;i<=c;i++)
		for(int j=0;j<(1<<12);j++)ret=max(ret,dp[a-1][b-1][j][i]);
	printf("%d\n",ret);
}

Volume 0とVolume 5が埋まったので、とにかく今度はICPC対策を…