Problem Description
The baseball game of planet Pandora is similar to the game of the Earth. In the game field, there are four bases which are named “home base”, “first base”, “second base” and “third base”. At the beginning, nobody is on the bases. There are two teams, one is the attacking team, and the other is the defending team.
One by one, all players of the attacking team goes to the home base and bats the ball thrown by the defending team.
There are four possible results of a bat:
1. “Out”. In this case, the batter misses the ball, so he is disqualified and leaves the game.
2.“Bingle”. In this case, the batter hits the ball, but the ball doesn’t fly out of the field. Then the batter can advance to the first base, and other players of the attacking team who are already on a base can advance to next base (The next base of the third base is the home base). If a player returns to the home base, he scores one point for his team.
3.“Allrun”. In this case, the batter hits the ball out of the field and then all the players on the bases (including the batter) can run to the home base and each scores one point for his team. So in this case, the attacking team can score at least 1 point, and at most 4 points.
4.“Sacrifice”. In this case, the batter chooses not to bat and leaves the field. According to the rule, in this case, the players still on the bases can advance to next base. So the player advancing to the home base this way scores one point. But if there have already been two batters who get an “Out” or a “Sacrifice” before, “Sacrifice” will end the game immediately and the attacking team can’t score any point in this “Sacrifice”.
According to the rule, a player must leave the field immediately after he scores one point for his team. The game ends after every player of the attacking team has batted once(A “Sacrifice” is also regarded as a bat), or after there has been 3 batters who get an “Out” or an “Sacrifice”.
Avatar is the coach of an attacking team. He knows that the same player performs differently when the player takes different turns. For example, if you let Jack to be the first batter, he will definitely get an “Out”, but if you let him play in the third turn, he will get an “Allrun”. Avatar knows his men very well. He asked you to find out the best “batting order” for his team. If the team bats in that order, their score will be maximized.
Input
There are multiple test cases, ended by 0.
For each test case:
The first line contains an integer n(1<=n <=15), meaning the number of players in Avatar’s team. All players are numbered for 1 to n.
Then a n×n matrix A follows. Aij describes what result the player i will get if he is the jth batter.( i and j start from 1 )
Following is the meaning of the value of Aij:
0 means the result is “Out”
1 means the result is “Sacrifice”
2 means the result is “Bingle”
3 means the result is “Allrun”
Output
For each test case, print one line containing the highest score Avatar’s team can get in the game.
Sample Input
5
0 2 0 1 2
1 0 2 0 2
0 2 1 2 0
0 2 2 1 2
2 1 0 2 0
0
Sample Output
Source
2010 National Programming Invitational Contest Host by ZSTU
Recommend
wxl
拖很久了,这题……一直有多校的比赛,一直木有时间做,昨天从后往前推果断tle,今天重新写了个A了。
很显然状态dp。
题意是告诉你第i个人打第j个球的情况,问你怎么排兵布阵使得总得分最高。
等于0表示击打不中出局
等于1表示不击打,自己下场,但是所有在垒上的队员抵达下一个垒,抵达本垒的加分,该击球手算出局,但是如果该击球手出局后出局人数达到3人则不加分,比赛直接结束
等于2表示击球成功,击球手上垒,所有在垒上的队员抵达下一个垒,抵达本垒+1分
等于3表示全垒打,所有在垒上的人跑到本垒加分,击球手也跑过1、2、3垒到本垒得分
比赛结束的情况可以是所有n个人都打完或者有3人出局。
dp[i][j][k]表示状态为i,三个垒的状态为j,已经出局k个人的时候最多得的分数。总体来说比较简单,注意以下几点:
1.预处理bit数组,即每个二进制数有多少个1,如果在循环里算由于很多数会重复算,所以tle。
2.位运算的优先级低到极点……开数组的时候(1<<15)+2忘了加括号提交果断tle。
代码
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
int dp[(1<<16)+2][10][4];
int map[17][17];
int bit[(1<<16)+2];
int main()
{
int i,j,n,cnt,k,l,m,p,a,ans;
for (i=0;i<(1<<16);i++)
{
cnt=0;
for (j=0;j<16;j++)
{
if ((i & (1<<j))!=0) cnt++;
}
bit[i]=cnt;
}
while(1)
{
scanf("%d",&n);
if (n==0) break;
for (i=0;i<n;i++)
{
for (j=0;j<n;j++)
{
scanf("%d",&map[i][j]);
}
}
memset(dp,-1,sizeof(dp));
ans=0;
dp[0][0][0]=0;
for (i=0;i<(1<<n);i++)
{
for (j=0;j<(1<<3);j++)
{
for (k=0;k<3;k++)
{
if (dp[i][j][k]==-1) continue;
ans=max(ans,dp[i][j][k]);
// printf("%d...%d...%d...%d\n",i,j,k,dp[i][j][k]);
if (k==3) continue;
for (l=0;l<n;l++)
{
if ((i & (1<<l))!=0) continue;
p=(i | (1<<l));
cnt=bit[p]-1;
if (map[l][cnt]==0)
{
dp[p][j][k+1]=max(dp[p][j][k+1],dp[i][j][k]);
}
if (map[l][cnt]==1)
{
if (k==2) continue;
if ((j & 4)!=0) dp[p][(j<<1) & 7][k+1]=max(dp[p][(j<<1) & 7][k+1],dp[i][j][k]+1);
else dp[p][(j<<1) & 7][k+1]=max(dp[p][(j<<1) & 7][k+1],dp[i][j][k]);
}
if (map[l][cnt]==2)
{
// printf("%d...%d...%d....%d.....%d....%d\n",p,((j<<1)&7)+1,k,dp[i][j][k],cnt,l);
if ((j & 4)!=0) dp[p][((j<<1) & 7)+1][k]=max(dp[p][((j<<1) & 7)+1][k],dp[i][j][k]+1);
else dp[p][((j<<1) & 7)+1][k]=max(dp[p][((j<<1) & 7)+1][k],dp[i][j][k]);
}
if (map[l][cnt]==3)
{
dp[p][0][k]=max(dp[p][0][k],dp[i][j][k]+((j & 1)!=0)+((j & 2)!=0)+((j & 4)!=0)+1);
}
}
}
}
}
printf("%d\n",ans);
}
return 0;
}