money
简单dp
力扣-122. 买卖股票的最佳时机 II
在这个题的基础上多维护一个最少操作数即可
code:
#include#define ll long long using namespace std; const int maxn = 1e5 + 9; int n; ll f[maxn][2], cnt[maxn][2]; void work() { cin >> n; for(int i = 0; i <= n; ++i) cnt[i][0] = cnt[i][1] = 0, f[i][0] = f[i][1] = -9e18; ll x; cin >> x; f[1][0] = 0; f[1][1] = -x; cnt[1][1] = 1; for(int i = 2; i <= n; ++i) { cin >> x; if(f[i-1][0] > f[i-1][1] + x) { f[i][0] = f[i-1][0]; cnt[i][0] = cnt[i-1][0]; } else if(f[i-1][0] < f[i-1][1] + x) { f[i][0] = f[i-1][1] + x; cnt[i][0] = cnt[i-1][1] + 1; } else f[i][0] = f[i-1][0], cnt[i][0] = min(cnt[i-1][0], cnt[i-1][1] + 1); if(f[i-1][1] > f[i-1][0] - x) { f[i][1] = f[i-1][1]; cnt[i][1] = cnt[i-1][1]; } else if(f[i-1][1] < f[i-1][0] - x) { f[i][1] = f[i-1][0] - x; cnt[i][1] = cnt[i-1][0] + 1; } else f[i][1] = f[i-1][1], cnt[i][1] = min(cnt[i-1][1], cnt[i-1][0] + 1); } cout << f[n][0] << " " << cnt[n][0] << endl; } int main() { ios::sync_with_stdio(0); int TT;cin>>TT;while(TT--) work(); return 0; }
另外
这个代码也能过,但是我感觉上边的转移才最正确
这个转移在利润相等的时候,它认为当前不买的操作数最少,但是感觉应该不一定吧
也可能这个贪心是对的
code:
#include#define ll long long using namespace std; const int maxn = 1e5 + 9; int n; ll f[maxn][2], cnt[maxn][2]; void work() { cin >> n; for(int i = 0; i <= n; ++i) cnt[i][0] = cnt[i][1] = 0, f[i][0] = f[i][1] = -9e18; ll x; cin >> x; f[1][0] = 0; f[1][1] = -x; cnt[1][1] = 1; for(int i = 2; i <= n; ++i) { cin >> x; if(f[i-1][0] >= f[i-1][1] + x) { f[i][0] = f[i-1][0]; cnt[i][0] = cnt[i-1][0]; } else if(f[i-1][0] < f[i-1][1] + x) { f[i][0] = f[i-1][1] + x; cnt[i][0] = cnt[i-1][1] + 1; } if(f[i-1][1] >= f[i-1][0] - x) { f[i][1] = f[i-1][1]; cnt[i][1] = cnt[i-1][1]; } else if(f[i-1][1] < f[i-1][0] - x) { f[i][1] = f[i-1][0] - x; cnt[i][1] = cnt[i-1][0] + 1; } } cout << f[n][0] << " " << cnt[n][0] << endl; } int main() { ios::sync_with_stdio(0); int TT;cin>>TT;while(TT--) work(); return 0; }



