取數字2
題目連結
上面取數字1的進階版,可以一樣定義,不過轉移式要稍微改變(其實就只是把原本只有2的區間擴大成k)
定義:$dp[i]$ 為取第i個數字的的最大值
轉移式:
$dp[i]=max(arr[j]+arr[i]),2k\leq i \leq n,i-2k\leq j \leq i-k$
轉移式比較複雜一點,不過就是取數字1的延伸
邊界:
$dp[i] = arr[i],1\leq i \leq k$
$dp[i]=max(arr[j]+arr[i]),k+1\leq i \leq 2k,1\leq j \leq i-k$
邊界的話,如果要說成是轉移式也是可以啦
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| #include <bits/stdc++.h> #define ios ios::sync_with_stdio(0),cin.tie(0); #define int long long using namespace std; int t;
signed main(){ ios; cin>>t; while(t--){ int n,arr[100005],k;cin>>n>>k; int dp[100005]; memset(dp,0,sizeof(dp)); memset(arr,0,sizeof(arr));
for(int i=1;i<=n;i++)cin>>arr[i]; for(int i=1;i<=k;i++)dp[i] = arr[i]; for(int i=k+1;i<=2*k;i++){ for(int j=1;j<=i-k;j++){ dp[i]=max(dp[i],arr[j]+arr[i]); } } for(int i=2*k+1;i<=n;i++){ for(int j = i-2*k;j<=i-k;j++){ dp[i] = max(dp[i],dp[j]+arr[i]); } } cout<<max_element(dp, dp+n+1)<<endl; } }
|