给定一周有n天,其中至少有1天为休息日,其余为工作日。同时给定一个长度为n的整型数组A,对于一个工作日,它能产生的工作值为A\(_{min(x,y)}\),其中x,y表示离该工作日最近的一个休息日(前一个,后一个)的时间。 我们通过举例可以发现:连续的k天工作日所能获得的工作值是固定的 k = 0:work\(_0\) = 0 所以我们考虑背包:背包的体积为n表示一周的工作时间和休息的总和 dp[i]表示 i 天所能获得的做大工作值E - Work or Rest
题目大意:
求每周工作所能获得的最大工作值。
解题思路:
例如:
给定A:10 10 1 1 1 1 1
k = 1:work\(_1\) = A\(_1\) = 10
k = 2:work\(_2\) = A\(_1\) + A\(_{min(1,2)}\) = 2*A\(_1\) = 20
k = 3:work\(_3\) = A\(_{min(1,3)}\) + A\(_2\) + A\(_{min(3,1)}\) = 2*A\(_1\) + A\(_2\) = 30
k = 4:work\(_4\) = A\(_{min(1,4)}\) + A\(_{min(2,3)}\)+A\(_{min(3,2)}\)+A\(_{min(4,1)}\) = 2*A\(_1\) + 2*A\(_2\) = 40
....
k = d: work = work\(_{d-1}\)+A\(_{(i+1)/2}\)
同时我们发现:对于一周的工作时间和休息的总和为n
物品p = d(体积)表示1天休息+连续(d-1)天所能获得的工作值
代码实现:
#include<bits/stdc++.h>
using namespace std;
# define int long long
# define endl "\n"
const int N = 2e5 + 10, inf = 1e18;
int pre[N];
int a[N];
void solve() {
int n;
cin >> n;
for(int i = 1;i <= n;++i) cin>>a[i];
for(int i = 1;i <= n;++i) pre[i] = pre[i-1]+a[(i+1)/2];
// for(int i = 1;i <= n;++i) cout<<pre[i]<<" \n"[i==n];
vector<int> f(n+1);
for(int i = 1;i <= n;++i){
for(int j = 1;j <= i;++j){
f[i] = max(f[i],f[i-j]+pre[j-1]);
}
}
cout<<f[n]<<endl;
}
int tt;
signed main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
tt = 1;
// cin >> tt;
while (tt--) solve();
return 0;
}