金币被放在1到n编号的格子中,一个人从第一个格子出发,有m张卡片,共4种,卡片上的数字1-4,表示可以走的步数。求到达终点获得的最大金币数。
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n=in.nextInt();
int m=in.nextInt();
int[] a=new int[n];
for(int i=0;i<n;i++){
a[i]=in.nextInt();
}
int[] b=new int[4];
for(int i=0;i<4;i++){
b[i]=in.nextInt();
}
Map<Integer,Integer> map=new HashMap<>();
map.put(0,a[0]);
int sum=0;
for(int i=3;i>=0;i--){
sum<<=6;
sum+=b[i];
}
for(int k=1;k<=sum;k++){
int[] step=steps(k);
boolean flag=true;
for(int i=0;i<4;i++){
if(step[i]>b[i]){
flag=false;
break;
}
}
if(!flag){
continue;
}
int pos=calSteps(k);
int cur=a[pos];
int max=0;
for(int i=0;i<4;i++){
if(step[i]>0){
int oldPos=getOldPos(step,i);
max=Math.max(max,map.getOrDefault(oldPos,0));
}
}
map.put(k,cur+max);
}
System.out.println(map.get(sum));
}
private static int getOldPos(int[] step,int j){
int ret=0;
for(int i=3;i>=0;i--){
ret<<=6;
ret+=step[i];
if(i==j){
ret--;
}
}
return ret;
}
private static int[] steps(int n){
int[] ret=new int[4];
for(int i=0;i<4;i++){
ret[i]=n&0x3f;
n>>=6;
}
return ret;
}
private static int calSteps(int n){
int ret=0;
for(int i=0;i<4;i++){
int x=n&0x3f;
ret+=(i+1)*x;
n>>=6;
}
return ret;
}
}