第一行输入一个整数
表示城市个数。
第二行输入
个整数
表示到达城市1到n可以获得的金币数量(第0个城市无法获得金币)。
在一行上输出一个整数表示答案;如果无法到达第
个城市,则输出
。
10 -1 2 3 4 -9 -9 -1 3 -1 -1
9
最优的方法是:第 1 步:使用跳跃 3 的卡牌,从 0 跳到 3 ,获得 3 枚金币;第 2 步:使用跳跃 1 的卡牌,从 3 跳到 4 ,获得 4 枚金币,共有 7 枚金币;第 3 步:使用跳跃 4 的卡牌,从 4 跳到 8 ,获得 3 枚金币,共有 10 枚金币;第 4 步:使用跳跃 2 的卡牌,从 8 跳到 10 ,获得 -1 枚金币,共有 9 枚金币。
import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Scanner; import java.util.Set; import java.util.TreeSet; public class Main { static List<List<Integer>> list = new ArrayList<>(); static boolean[] vis = new boolean[5]; static int[] b = new int[4]; private static void fun(int cnt) { if (cnt == 4) { list.add(Arrays.asList(b[0], b[1], b[2], b[3])); return; } for (int i = 1; i <= 4; i++) { if (!vis[i]) { vis[i] = true; b[cnt++] = i; fun(cnt); vis[i] = false; cnt --; } } return; } public static void main(String[] args) { Scanner in = new Scanner(System.in); Arrays.fill(vis, false); int n = in.nextInt(); int[] a = new int[n + 1]; for (int i = 1; i <= n; i++) { a[i] = in.nextInt(); } fun(0); int x = n / 10; int y = n % 10; int now = 0; long ans = 0; for (int i = 0; i < x; i++) { long res = (long)-1e18; boolean q = false; for (List<Integer> lst : list) { int u = now; long temp = 0; int j = 0; for (j = 0; j < 4; j++) { u += lst.get(j); temp += 1l * a[u]; if (ans + temp < 0) break; } if (j == 4) q = true; res = Math.max(res, temp); } if (!q) { System.out.println(-1); return; } now += 10; ans += res; } long res = ans; boolean q = (now == n); for (List<Integer> lst : list) { int u = now; long temp = 0; for (int i = 0; i < 4; i++) { u += lst.get(i); if (u > n) break; temp += 1l * a[u]; if (res + temp < 0) break; if (u == n) { q = true; ans = Math.max(ans, res + temp); break; } } } System.out.println(q ? ans : -1); } }
n = int(input()) arr = list(map(int, input().split())) def step(start, gold): if len(stack) == 4 or start == n-1: earn.append(gold) for i in card: idx = start + i if i not in stack and idx < n: gold_idx = gold + arr[idx] if gold_idx >= 0: stack.add(i) step(idx, gold_idx) stack.remove(i) card = [1, 2, 3, 4] stack = set() money = 0 flag = True cur_start = -1 while cur_start + 1 < n: earn = [] step(cur_start, money) if earn: money = max(earn) else: flag = False break cur_start += 10 print(money if flag else -1)
#include <iostream> #include<vector> using namespace std; long long res = INT32_MIN; void backtracking(const vector<long long>& city, long long pos, long long money, vector<bool>& used, int step) { if(money < 0) return ; if(pos > city.size()-1) return ; if(step == 4 || pos == city.size()-1) { res = max(res, money); return ; } for(int i=1; i<=4; i++) { if(used[i]==false && money+city[pos+i]>=0 && pos+i<=city.size()-1) { used[i]=true; backtracking(city, pos+i, money+city[pos+i], used, step+1); used[i]=false; } } } int main() { int n; cin >> n; vector<long long> city(n+1); for(int i=1; i<=n; i++) cin >> city[i]; long long final_res = 0; int i=0; long long money = 0; for(; i<n/10; i++) { res = INT32_MIN; vector<bool> used(5, false); backtracking(city, i*10, money, used, 0); if(res == INT32_MIN) { cout<<-1<<endl; break; } else{ money = res; } } if(res != INT32_MIN) { if((i+1)*10 > n && i*10 < n) { res = INT32_MIN; vector<long long> city_part(city.begin()+i*10, city.end()); vector<bool> used(5, false); backtracking(city, i*10, money, used, 0); if(res == INT32_MIN) { cout<<-1<<endl; } else money = res; } if(res != INT32_MIN) cout<<money<<endl; } }
public class BigRichGame { public static void main(String[] args) { int[] cityCoin = {-1, 2, 3, 4, -9, -9, -1, 3, -1, -1, 10, -1, 20}; int result = getResult(cityCoin); if (result == Integer.MIN_VALUE) { System.out.println("没有合适的组合到达n城市"); } else { System.out.println("最大金币值:" + result); } } //将数组拆分成很多个10步 public static int getResult(int[] cityCoin) { int[] steps = {1, 2, 3, 4}; int res = 0; int l = cityCoin.length - 1; int r = -1; while (r < l) { int n = Math.min(r + 10, l); LinkedList<Integer> roundStep = new LinkedList<>(); int max = getGoldCoin(cityCoin, r, n, steps, r, roundStep); res += max; r += 10; } return res; } //每十步的最优解 public static int getGoldCoin(int[] cityCoin, int r, int n, int[] steps, int start, LinkedList<Integer> roundStep) { //如果已经到达n城市则不需要再往前,直接返回我所有拿到的值 if (r == n) { return cityCoin[n]; } int max = Integer.MIN_VALUE; for (int step : steps) { int next = r + step; //如果大于n则直接结束 if (next > n) { continue; } if (roundStep.contains(step)) { continue; } roundStep.add(step); int nextAns = getGoldCoin(cityCoin, next, n, steps, start, roundStep); int nowAns = r != start ? cityCoin[r] : 0; int ans = nextAns == Integer.MIN_VALUE ? Integer.MIN_VALUE : Math.max(max, nowAns + nextAns); max = Math.max(ans, max); roundStep.removeLast(); } return max; } }
package main import ( "fmt" "math" ) func main() { var count int fmt.Scan(&count) var city = make([]int64, count) for i := 0; i < count; i++ { fmt.Scan(&city[i]) if city[i] < -1000000000 || city[i] > 1000000000 { fmt.Println("error") } } var card = make(map[int]bool, 4) for i := 1; i <= 4; i++ { card[i] = true } var maxCoin int64 var globalMaxCoin int64 var coin int64 step := -1 maxCoin = 0 globalMaxCoin = 0 coin = 0 for step < count - 2 { for i := 1; i <= 4; i++ { card[i] = false step = step + i coin += city[step] for j := 1; j <= 4; j++ { if card[j] == true { card[j] = false step = step + j coin += city[step] for k := 1; k <= 4; k++ { if card[k] == true { card[k] = false step = step + k coin += city[step] for l := 1; l <= 4; l++ { if card[l] == true { card[l] = false step = step + l coin += city[step] if coin > maxCoin { maxCoin = coin } card[l] = true coin -= city[step] step = step - l } } card[k] = true coin -= city[step] step = step - k } } card[j] = true coin -= city[step] step = step - j } } card[i] = true coin -= city[step] step = step - i } step = step + 10 globalMaxCoin += maxCoin coin = 0 maxCoin = -math.MaxInt64 } if step == count - 1 { fmt.Println(globalMaxCoin) return } fmt.Println(-1) }
import sys def fn(init_curr, numbers): l = [[0 for _ in range(4)] for _ in range(10)] l[0][0] = numbers[0] + init_curr l[1][1] = numbers[1] + init_curr l[2][2] = numbers[2] + init_curr l[3][3] = numbers[3] + init_curr l[2][0] = max(l[0][0], l[1][1]) + numbers[2] if max(l[0][0], l[1][1]) > 0 else -1 l[3][0] = max(l[0][0], l[2][2]) + numbers[3] if max(l[0][0], l[2][2]) > 0 else -1 l[4][0] = max(l[0][0], l[3][3]) + numbers[4] if max(l[0][0], l[3][3]) > 0 else -1 l[4][1] = max(l[1][1], l[2][2]) + numbers[4] if max(l[1][1], l[2][2]) > 0 else -1 l[5][0] = ( max(l[4][1], l[3][0], l[2][0]) + numbers[5] if max(l[4][1], l[3][0], l[2][0]) > 0 else -1 ) l[5][1] = max(l[1][1], l[3][3]) + numbers[5] if max(l[1][1], l[3][3]) > 0 else -1 # [[0, 1, 3], [], [2, 3]], l[6][0] = ( max(l[5][1], l[4][0], l[2][0]) + numbers[6] if max(l[5][1], l[4][0], l[2][0]) else -1 ) l[6][2] = max(l[2][2], l[3][3]) + numbers[6] if max(l[2][2], l[3][3]) > 0 else -1 # [[0, 2, 3]], l[7][0] = ( max(l[6][2], l[4][0], l[3][0]) + numbers[7] if max(l[6][2], l[4][0], l[3][0]) > 0 else -1 ) # 1, 2, 3 l[8][1] = ( max(l[6][2], l[5][1], l[4][1]) + numbers[8] if max(l[6][2], l[5][1], l[4][1]) > 0 else -1 ) l[9][0] = ( max(l[8][1], l[7][0], l[6][0], l[5][0]) + numbers[9] if max(l[8][1], l[7][0], l[6][0], l[5][0]) > 0 else -1 ) return l[9][0] # aaa_maps = [[0 for _ in range(4)] for _ in range(10)] count = int(sys.stdin.readline()) numbers = sys.stdin.readline().split() numbers = [int(val) for val in numbers] numbers = numbers + ([0] * (10 - len(numbers) % 10) if len(numbers) % 10 > 0 else []) lp = len(numbers) // 10 init_curr = 0 for l in range(lp): init_curr = fn(init_curr, numbers[l * 10 : l * 10 + 10]) if init_curr < 0: break print(init_curr if init_curr >= 0 else -1)
#include<bits/stdc++.h> using namespace std; typedef long long LL; typedef unsigned long long ull; int dx[]={1,-1,0,0},dy[]={0,0,1,-1}; typedef pair<int,int>PII; typedef pair<int,__int128>PI; typedef pair<double,double>PDD; typedef pair<LL,LL>PLL; typedef tuple<LL,LL,LL,LL>t4i; typedef tuple<int,int,int>t3i; const long double eps=1e-7; const int inf=0x3f3f3f3f; const long long INF=1e18; const double pai=acos(-1.0); const int mod=1e9+7; const int N=1e5+10,M=2e6+10; mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count()); //__builtin_popcountll(x) LL dp[N],a[N]; int p[5]; void solve() { int n;cin>>n; for(int i=1;i<=n;i++) cin>>a[i],dp[i]=-INF; dp[0]=0; queue<PLL>q; q.push({0,0}); while(q.size()){ auto [ps,nw]=q.front();q.pop(); if(nw<dp[ps]) continue; for(int i=1;i<=4;i++) p[i]=i; do{ LL pos=ps,now=nw; bool ok=true; for(int i=1;i<=4;i++){ LL x=pos+p[i]; if(x<=n&&now+a[x]>=0) dp[x]=max(dp[x],now+a[x]),pos=x,now+=a[x]; else{ ok=false; break; } } if(ok) q.push({pos,now}); }while(next_permutation(p+1,p+5)); } if(dp[n]>=0) printf("%lld\n",dp[n]); else printf("-1\n"); } int main() { ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); int tt;tt=1; //cin>>tt; while(tt--){ solve(); } return 0; }
import java.util.Scanner; public class Main { static long max=Integer.MIN_VALUE; static int[] step=new int[]{1,2,3,4};//走1 2 3 4步的卡牌 public static void normoaltune(int start,long[] num,long coin,int steps,int[] flag){ //往后走十步的所有可能情况 取最大值 if (coin<0) return ; if (steps==4){ max=Math.max(max,coin); return; } for (int i = 0; i < 4; i++) {//依次使用卡牌 获取到硬币 if (flag[i]==0){//没有被使用过 flag[i]=1;//标记为使用 normoaltune(start+step[i],num,coin+num[start+step[i]],steps+1,flag); flag[i]=0;//回溯为未使用的状态 } } } public static void lasttune(int start,int finalstep,long[] num,long coin,int[] flag){//最后几步路 if (coin<0)//小于0 坠机 return ; if (start>finalstep)//越过了 坠机 return; if (start==finalstep){//到达终点 保存最大值 max=Math.max(max,coin); } for (int i = 0; i < 4; i++) { if (flag[i]==0&&start+step[i]<=finalstep){//卡牌没有被使用过 这段代码类似于走10步的代码 flag[i]=1;//标记为使用 lasttune(start+step[i],finalstep,num,coin+num[start+step[i]],flag); flag[i]=0;//回溯为未使用的状态 } } } public static void main(String[] args) { Scanner in = new Scanner(System.in); int n = in.nextInt(); in.nextLine(); long[] nums=new long[n+1]; for (int i = 0; i < n; i++) { nums[i+1]=in.nextLong(); } int nor=n/10;//完整的十步 int last=n%10;//最后几步 long coin=0; boolean isreach=false; for (int i = 0; i < nor; i++) { max=Integer.MIN_VALUE;//初始化为最小值 int[] flag=new int[4]; normoaltune(i*10,nums,coin,0,flag);//往后走十步 coin=max; if (coin<0) { //到不了 寄了 isreach=true; break; } } if (isreach){//到不了 System.out.println(-1); }else{ //能到 if (last==0)//正好是10的倍数 那就不用走最后几步了 System.out.println(coin); else {//否则要走最后几步 max=Integer.MIN_VALUE;//初始化为最小值 int[] flag=new int[4]; lasttune(n-last,n,nums,coin,flag); coin=max; if (coin<0)//硬币为负 到不了终点 System.out.println(-1); else//为正就输出 System.out.println(coin); } } } }