第一题
基本思路写在注释里了
不提示的话,状态压缩+DP的方法还是蛮难想到的
import java.util.Arrays;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
while(true) {
int[] dp = new int[1<<19+1];//包含了所有袋子中的状态,如{000……01}表示只放入了第一种糖
int[][] M = new int [100][100];//按照输入矩阵格式存储
int[] state = new int[100];//存储每一袋子的状态
int n = in.nextInt();//袋数
int m = in.nextInt();//种类数
int k = in.nextInt();//每袋数
Arrays.fill(dp, -1);//Arrays的静态方法,你们用C的就用memset
dp[0]=0;
for(int i=0; i<n; i++)
{
for(int j=0; j<k; j++)
{
M[i][j] = in.nextInt();
state[i] |= 1<<(M[i][j]-1);
}
dp[state[i]]=1;//表示这种状态(state[i])只要一袋
}
for(int i=0; i<n; i++)
{
for(int j=0; j<=(1<<(m)); j++)
{
if(dp[j]==-1)continue;
if(dp[j|state[i]]==-1||dp[j|state[i]]>dp[j]+1)
dp[j|state[i]]=dp[j]+1;
}
}
System.out.println(dp[(1<<m)-1]);//如果袋子中种类不全就返回-1;注意加括号,因为1<<m
}
}
}
第二题
import java.util.Scanner;
public class Main {
public static int calc(int i,int state, int[][] a) {
int sum = 0;
int cnt = 1;
while(state!=0) {
if((state&1)!=0)sum+=a[i][cnt];
cnt++;state/=2;
}
return sum;
}
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int[][] a = new int[n+1][n+1];
int[][] dp = new int[n+1][(1<<n)];
for(int i=1; i<=n; i++) {
for(int j=1; j<=n; j++){
a[i][j] = in.nextInt();
}
}
for(int i=1; i<=n; i++) {
for(int j=0; j<(1<<n); j++) {
if(((j<<1)&j)!=0)continue;
int val = calc(i,j,a);
for(int k=0; k<(1<<n); k++) {
if(((k<<1)&k)!=0)continue;
if((j&k)!=0)continue;
dp[i][j]=Math.max(dp[i][j], dp[i-1][k]+val);
}
}
}
int max = 0;
for(int i=0; i<(1<<n); i++) {if(((i<<1)&i)==0)max = Math.max(dp[n][i], max);}
System.out.println(max);
}
}
第三题
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt(),m = in.nextInt();
int[]state = new int[n+1];
int[][][] dp = new int[n+1][1<<m][1<<m];
int[] law = new int[1<<m];
int cnt=0;
for(int i=0;i<(1<<m);i++)
{
if(((i&(i>>2))==0)&&( ((i>>1)&i)==0)) {law[cnt++]=i;}
}
for(int i=1;i<=n;i++) {
String temp = in.next();
for(int w=0;w<m;w++) {
char tpc = temp.charAt(w);
if(tpc=='H')state[i]|=(1<<w);
}
int sum = 0;
for(int j=0; j<cnt; j++) {
if((state[i]&law[j])!=0)continue;
for(int k=0; k<cnt; k++) {
if((state[i-1]&law[k])!=0)continue;
if((law[j]&law[k])!=0)continue;
for(int l=0; l<cnt; l++) {
if(i>1&&(state[i-2]&law[l])!=0)continue;
if((law[k]&law[l])!=0)continue;
if((law[j]&law[l])!=0)continue;
int val = Integer.bitCount(law[j]);
dp[i][j][k] = Math.max(dp[i][j][k], dp[i-1][k][l]+val);
}
}
}
}
int maxi = 0;
for(int i=0;i<cnt;i++) {
for(int k=0;k<cnt;k++) {
if((law[i]&law[k])!=0)continue;
maxi = Math.max(maxi, dp[n][i][k]);
}
}
System.out.println(maxi);
}
}