あなたの教室の席分布のM * nの行列表現の座席を与えます。シートは、(利用できない)悪い場合、使用「#」を示し、それ以外の場合、で表されます「」。
学生は左に見ることができ、右、左上、右上次の彼の学生の4つの方向への答えが、生徒たちは彼が答えのか、後ろの正面に座って見ることができません。仕事とリターン一緒に試験を受けて、検査室が保持できるごまかすことができない学生の最大数をしてください。
学生は席に座って良好な状態でなければなりません。
例1:
入力: ""席= [[ "#" ,, "#"、 "#" ,, "#"]、 ""
。"" [ "#"、 "#"、 "#"、「# 。 "" "]、
[" # "" "" # "" # "" "" #「]]。
出力:4
説明すると:教師は生徒が利用可能な4つの席に座るできるようにすることができますそう、彼らは試験でカンニングすることはできません。
例2:
入力:. ""席= [[ "#"]、
[ "#"、 "#"]、
[ "#"、] ,. ""
[ "#"、 "#"]、
[ "" 「#」]]
出力:3
説明:すべての学生が利用できる座席に座ってみましょう。
例3:
输入: "" "" ""席= [[ "#"、、、、 "#"]、
" " "" "" [、" #"、 "#"、]、
[ " ""。 "" #"、 ""、 ""]、
[ " "" #"、 ""、 "#"、 ""]、
[ "#"、 "。 」、 ""、 ""、 "#"]]。。
输出:10
解释:让学生坐在第1,3和5列的可用座位上。
ヒント:
唯一の文字シート及び'#' ''
M == seats.length
N-席== [I] .LENGTH
1 <= M <= 8。。
1 <= N - <= 8。
アイデア:圧力DPのような、状態遷移の正しい実装をすることができ、違法な状況を削除、現在の状態と(バイナリ表現)の前の行を列挙する。
class Solution {
public int maxStudents(char[][] seats) {
int m=seats.length;
int n=seats[0].length;
int len=1<<n;
int[][] dp=new int[m][len];
for(int i=0;i<len;i++) {
int num=0;
for(int j=0;j<n;j++) {
if(((i>>j)&1)!=0) {
if(seats[0][j]=='.') num++;
else {
num=0;
break;
}
}
if(j>0 && ((i>>j)&1)==1 && ((i>>j-1)&1)==1) {
num=0;
break;
}
}
dp[0][i]=num;
}
for(int i=1;i<m;i++)
for(int j=0;j<len;j++) {
for(int k=0;k<len;k++) {
int num=0;
boolean flag=false;
for(int h=0;h<n;h++) {
int x1=(j>>h-1)&1;
int x2=(j>>h+1)&1;
int x3=(k>>h)&1;
int x4=(k>>h-1)&1;
if(h>0 && x1+x3==2 || h<n-1 && x2+x3==2 || h>0 && x3+x4==2 || seats[i][h]=='#' && x3==1)
flag=true;
if(((k>>h)&1)==1) num++;
}
if(!flag) dp[i][k]=Math.max(dp[i][k], dp[i-1][j]+num);
}
}
int ans=0;
for(int i=0;i<len;i++)
ans=Math.max(ans, dp[m-1][i]);
return ans;
}
}