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;
}