橙色dp

P1944 最长括号匹配

f[i]表示以s[i]为结尾的最长规范括号序列
s[i] = ( || s[i] = [ 时 f[i] = 0
s[i] = ) && s[i - 1 - f[i - 1]] = ( 时 f[i] = f[i - 1] + 2 + f[i - 2 - f[i - 1]]]
s[i] = ] && s[i - 1 - f[i - 1]] = [ 时 f[i] = f[i - 1] + 2 + f[i - 2 - f[i - 1]]]

代码
int f[1000010];
string s;

void solve() {
    cin >> s;
    int k = 0;
    for(int i = 0; i < s.size(); i ++){
        if(s[i] == ']'){
            if(s[i - 1 - f[i - 1]] == '[') 
                f[i] = f[i - 1] + 2 + f[i - 2 - f[i - 1]];
        }else if(s[i] == ')'){
            if(s[i - 1 - f[i - 1]] == '(') 
                f[i] = f[i - 1] + 2 + f[i - 2 - f[i - 1]];
        }
        if(f[k] < f[i]) k = i;
    }
    cout << s.substr(k - f[k] + 1, f[k]) << endl;
}

P1977 出租车拼车

背包模型,讨论第i辆车载几个人

代码
const int MAX_N = 1e5 + 5;
const ll MOD = 1e9 + 7;
const ll INF = 0x3f3f3f3f;
const ld EPS = 1e-9;

int n, k, d, s;
int f[110][110]; // f[i,j] 表示前i辆车载j个人到终点的最小花费
int c[110]; // 每辆车能载的人数
int t[110]; // 每辆车到达的时间

void solve() {
    cin >> n >> k >> d >> s;
    for(int i = 1; i <= k; i ++) cin >> t[i] >> c[i];
    memset(f, 0x3f, sizeof f);
    for(int i = 0; i <= k; i ++) f[i][0] = 0; // 前i辆车总共0个人的最小花费为0
    for(int i = 1; i <= k; i ++){
        for(int j = 1; j <= n; j ++){
            f[i][j] = f[i - 1][j];
            for(int u = 1; u <= c[i]; u ++){
                f[i][j] = min(f[i - 1][j - u] + u * t[i] + d, f[i][j]);
            }
        }
    }
    int ans = INF;
    for(int i = 0; i <= k; i ++)
        ans = min(ans, f[i][n]);
    if(ans == INF) cout << "impossible" << endl;
    else cout << ans << endl;
}
posted @ 2022-02-08 12:04  yys_c  阅读(25)  评论(0编辑  收藏  举报