标签:int main 代码 sizeof void www 不同 com ems
状态机dp感觉还挺有趣的 主要就是利用dp数组 将题意说表达的要求细分为不同的状态 达到削减时间的目的
比如https://www.acwing.com/problem/content/1059/ acwing的这道股票购买IV
这道题给了一组数字我可以在任意时间购入一个股票 并在之后卖出 但在同一时间内我只能持有一股 同时有个交易次数的上限
依照此描述 我们就可以设置一个dp数组f[i][j][k]表示 在前i个物品中买j个物品所获得的收益 其中k = 0表示不持有股票 k = 1表示持有股票
这样我们就可以得到一个状态转移方程
f[i, j, 0]可由在f[i - 1, j, 0]和f[i - 1, j, 1] + w[i]所表示
即在前i - 1个物品中购买j个物品,同时没有持有股票 和 在前i - 1个物品中购买j个物品,此刻卖出股票 表示
f[i, j, 1]可由f[i - 1, j, 1]和f[i - 1, j - 1, 0] - w[i]所表示
即在前i - 1个物品中购买j个物品,并且持有股票 和在前i - 1个物品中购买j - 1个物品,此刻购买股票 表示
因为并不一定交易次数越多,收益就越多 显而易见,最后持有股票一定比卖出股票的收益低 所以答案就在f[n, 0 ~ m, 0]中存在
下面是代码hhhh
const int N = 100010, M = 110;
int n, m, l[N];
int f[N][M][2];
int main(void)
{
cin >> n >> m;
for(int i = 1; i <= n; i ++ ) cin >> l[i];
memset(f, -0x3f, sizeof f);
for(int i = 0; i <= n; i ++ ) f[i][0][0] = 0;
for(int i = 1; i <= n; i ++ )
for(int j = 1; j <= m; j ++ )
{
f[i][j][0] = max(f[i - 1][j][0], f[i - 1][j][1] + l[i]);
f[i][j][1] = max(f[i - 1][j][1], f[i - 1][j - 1][0] - l[i]);
}
int ans = 0;
for(int i = 0; i <= m; i ++ )
ans = max(ans, f[n][i][0]);
cout << ans;
}
标签:int main 代码 sizeof void www 不同 com ems
原文地址:https://www.cnblogs.com/yzzlqyxc/p/14454063.html