题意:给出一个序列 a,要求求出一个单调递增的下标序列 b,使得 ab1-ab2+ab3-ab4+⋯ 最大,输出这个最大值。
思路:暴力肯定会t,我们用dp来写。dp[i][j],i表示前i个数在j状态下的最大值,j的值为0或1,0表示当前应当减去ai,1表示当前应当加上ai。
所以我们不难写出转移方程,dp[i][0]=max(dp[i-1][1]-a[i],dp[i-1][0]),dp[i][1]=max(dp[i-1][0]+a[i],dp[i-1][1]),因为不知道最后一个数是加还是减,输出前比较一下即可
代码:
#include <set> #include <map> #include <stdio.h> #include <string.h> #include <cmath> #include <algorithm> #include <iostream> #include <vector> #include <queue> #define pb push_back #define IOS ios::sync_with_stdio(false);cin.tie(0); cout.tie(0) #define fi first #define se second using namespace std; const int INF = 0x3f3f3f3f;//????? typedef long long ll; typedef long double ld; typedef pair<ll, int> pll; typedef pair<int, int> pii; const int N = 1000000; int a[100005],b[105],prime[N],st[N];ll sum[N]; int cnt=0; ll dp[300005][2]; string s; ll qpow(ll x,ll y,ll mod) { int ans=1; while(y) { if(y&1) ans=ans*x%mod; x=x*x%mod; y>>=1; } return ans%mod; } void ola() { for(int i=2;i<=1000000;i++) { if(st[i]==0) { prime[cnt++]=i; } for(int j=0;j<cnt&&i*prime[j]<=1000000;j++) { st[i*prime[j]]=1; if(i%prime[j]==0) break; } } } int main() { IOS; int t; cin >> t; while(t--) { int n,q; cin >> n >> q; ll ans=0;int maxn=-INF; for(int i=1;i<=n;i++) { cin >> a[i]; } dp[1][1]=a[1],dp[1][0]=0; for(int i=2;i<=n;i++) { dp[i][0]=max(dp[i-1][1]-a[i],dp[i-1][0]); dp[i][1]=max(dp[i-1][0]+a[i],dp[i-1][1]); } cout << max(dp[n][0],dp[n][1]) << endl; } return 0; }