解法1:动态规划

设置一个状态转移数组dp,dp[i]表示数组中前i个元素所能偷的最大金额是多少
状态转移表达式:
(1)对于当前的元素arr[i],如果偷,那么dp[i] = dp[i-2] + arr[i]
(2)如果不偷,那么dp[i] = dp[i-1]

    public long subsequence (int n, int[] array) {
        // write code here
        long[] dp=new long[n+1];// dp[i] 表示当前 i 个最大和
        dp[0]=0;
        dp[1]=array[0];
        for(int i=2;i<=n;i++){
            // 当前的最大值在前一个或者前两个和现在的和之间选择
            dp[i]=Math.max(dp[i-1],dp[i-2]+array[i-1]);
        }
        return dp[n];
    }

解法2:循环

逆序遍历

    public long subsequence (int n, int[] array) {
        // write code here
        long a=0,b=0,c=0;
        for(int i=n-1;i>=0;i--){
            c=Math.max(a,array[i]+b);
            b=a;
            a=c;
        }
        return c;
    }

正序遍历

    public long subsequence (int n, int[] array) {
        // write code here
        long a=0,b=0;
        //因为dp[i]只与dp[i-1]和dp[i-2]有关
        //所以分别定义两个数表示dp[i-1]和dp[i-2];
        for(int i=0;i<n;i++){
            long tmp=Math.max(b,a+array[i]);
            //相当于dp[i]=max(dp[i-1],dp[i-2]+array[i]);
            a=b;
            b=tmp;
        }
        return b;
    }