加载中...

状态机

大盗阿福https://www.acwing.com/problem/content/1051/

f[i][0]表示不偷第i家的最大费用
两个状态 偷这家+不偷这家+

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 1e5+10;

int w[N],f[N][3];
const int inf =1e9; 
int main()
{
    int t;
    
    cin >> t;
    //0未选择店铺 1表示选择 
    while (t -- ){
        int n;cin>>n;
        for (int i = 1; i <= n; i ++ ){
            cin >> w[i];
        }
        f[0][0]=0,f[0][1]=0 ;//初始化0为入口 值为0   
        for (int i = 1; i <= n; i ++ ){
            f[i][0]=max(f[i-1][0],f[i-1][1]);//f[i][j]表示第i层是选择了还是没选
            f[i][1]=f[i-1][0]+w[i];//只能上层没选择的那种走过来
        }
        cout << max(f[n][1],f[n][0])<<endl;
    }
    
    
    return 0;
}

股票买卖4 有限制次数的交易 https://www.acwing.com/activity/content/problem/content/1288/

两个状态 手中有股票 手中无股票
f[i][j][0] 第i天 进行第j次交易

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 1e5+10, inf =0x3f3f3f3f3f;
int w[N],f[N][110][2];
int main()
{
    int n,k;cin>>n>>k;
    for (int i = 1; i <= n; i ++ ){
        cin >> w[i];
    }
    memset(f, -0x3f, sizeof f);//求最大值 初始化为负无穷 下面再讨论 
    for (int i = 0; i <= n; i ++ ) f[i][0][0]=0;//一次交易都没有进行所以f为0

    for (int i = 1; i <= n; i ++ )
        for (int j = 1; j <= k; j ++ ){
        f[i][j][0]=max(f[i-1][j][1]+w[i],f[i-1][j][0]);
        f[i][j][1]=max(f[i-1][j-1][0]-w[i],f[i-1][j][1]);//j次如果交易由j-1得来
    }
    int res=0;
    for (int i = 1; i <= k; i ++ ){//不一定用完交易的次数
        res=max(res,f[n][i][0]);
    }
    cout << res;
    return 0;
}

股票交易5 https://www.acwing.com/activity/content/problem/content/1289/

卖出后不能立刻买入 需要冷却一天
多了一个状态 手中无货第一天的自动跳动第二天 设置入口为第二天的状态

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 1e5+10,inf=0x3f3f3f3f;
int w[N],f[N][3];//0表示手有货 1表示卖出的第一天就是卖出货 2表示卖出的第二天
int n;

int main()
{
    cin >> n;
    f[0][0]=f[0][1]=-inf;//无限小表示不考虑这个状态,就是不是入口
    f[0][2]=0;//这个状态为入口 所以设为0
    for (int i = 1; i <= n; i ++ ) cin >> w[i];
    for (int i = 1; i <= n; i ++ ){
        f[i][0]=max(f[i-1][0],f[i-1][2]-w[i]);
        f[i][1]=f[i-1][0]+w[i];
        f[i][2]=max(f[i-1][1],f[i-1][2]);
    }
    cout <<max( f[n][1],f[n][2]);//两个状态都可能成为答案  
    
    return 0;
}
posted @ 2022-07-23 17:32  liang302  阅读(13)  评论(0编辑  收藏  举报