动态规划之状态机

大盗阿福

大盗阿福

状态机
动态规划之状态机_第1张图片

算法思路:

//状态表示:
//      f[i]表示抢劫前i家店铺的收益
//状态计算    
//      抢第i家:  f[i - 2] + w[i]
//      不抢第i家:f[i - 1]
//状态分解:
//  f[i] = 0:未选最后一个店铺
//  f[i] = 1:选择最后一个店铺

//

//状态表示:
//      f[i][j]:所有走了i步,且当前位于状态j的所有走法
//属性:
//      max
//状态计算:
//      f[i][0]:    最后一步0->0    |       最后一步1->0
//                  f[i - 1][0]       |       f[i-1][1]
//      f[i][1]:    最后一步0->1
//                  f[i - 1][0] + w[i]
#include 
#include 
#include 
using namespace std;

const int N = 100010, INF = 0x3f3f3f;

int n;
int w[N], f[N][2];

int main(){
    int T;
    cin >> T;
    while(T --){
        cin >> n;
        for(int i = 1; i <= n; i ++) cin >> w[i];
        
        //状态机入口:从0开始,不能取到1
        f[0][0] = 0, f[0][1] = -INF;
        
        for(int i = 1; i <= n; i ++){
            f[i][0] = max(f[i - 1][0], f[i - 1][1]);
            f[i][1] = f[i - 1][0] + w[i];
        }
        
        cout << max(f[n][0], f[n][1]) << endl;
    }
    return 0;
}

股票买卖IV

股票IV状态机

状态机模型
动态规划之状态机_第2张图片

//两种状态:
//      k = 0: 手中无货
//      k = 1:手中有货

//状态表示:f[i][j][k]:代表交易了i天,已经交易了j次,状态为k

//属性:max

//状态计算:
//      f[i][j][0]:    最后一步 0 -> 0 |    最后一步 1 -> 0
//                      f[i - 1][j][0] |    f[i - 1][j][1] + w[i]
//
//      f[i][j][1]:    最后一步 1 -> 1 |   最后一步 0 -> 1
//                      f[i - 1][j][1] |    f[i - 1][j - 1][0] - w[i]

//理解:
//  1->0:表示 手中有货 变为 手中无货,并且当前正在进行交易,还未交易完成,只有将w[i]加上才能够算交易完成
//  0->1:j表示正在进行第j次交易,当前正在交易的钱f[i][j][1] 等于 尚未交易的钱 减去 购买的钱
#include 
#include 
#include 
using namespace std;

const int N = 100010, M = 110, INF = 0x3f3f3f;
int n, k;
int f[N][M][2];
int w[N];

int main(){
    cin >> n >> k;
    for(int i = 1; i <= n; i ++) cin >> w[i];
    
    //初始化
    memset(f, -INF, 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 <= k; j ++){
            f[i][j][0] = max(f[i - 1][j][0], f[i - 1][j][1] + w[i]);
            f[i][j][1] = max(f[i - 1][j][1], f[i - 1][j - 1][0] - w[i]);
        }
    
    int res = 0;
    for(int i = 1; i <= k; i ++) res = max(res, f[n][i][0]);
    
    cout << res << endl;
    return 0;
}

股票买卖V

股票买卖V

股票买卖自动机

动态规划之状态机_第3张图片

#include 
#include 
#include 
using namespace std;

const int N = 100010;
int f[N][3];
int n;
int w[N];

int main(){
    cin >> n;
    for(int i = 1; i <= n; i ++) cin >> w[i];
    
    memset(f, -0x3f3f3f, sizeof f);
    f[0][2] = 0;
    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]) << endl;
    
    return 0;
}

你可能感兴趣的:(算法,数据结构,数据结构)