#include <bits/stdc++.h>
using namespace std;
const int ms = 1e5+5;
const int inf = 0x3f3f3f3f;
int m[ms], f[ms];
int isEmpty[ms];
int dp[3005][3005][2][2];
main() {
int n;
cin >> n;
int qntM = 0;
for(int i = 0; i < n; i++) {
cin >> m[i] >> f[i];
qntM += m[i];
}
if(qntM == 0) {
cout << 0 << '\n';
return 0;
}
int empt = 0;
for(int i = 0; i < n; i++) {
if(m[i] == 0 && f[i] == 0) {
isEmpty[i] = 1;
empt++;
}
}
for(int i = 0; i < n; i++) {
if(isEmpty[i]) continue;
f[i] = f[i] - 1;
}
for(int j = 0; j <= empt; j++) {
dp[n][j][1][1] = 0;
dp[n][j][0][1] = inf;
dp[n][j][1][0] = inf;
dp[n][j][0][0] = inf;
}
for(int i = n-1; i >= 0; i--) {
for(int j = 0; j <= empt; j++) {
for(int hasSo = 0; hasSo < 2; hasSo++) {
for(int hasUm = 0; hasUm < 2; hasUm++) {
int &ans = dp[i][j][hasSo][hasUm];
ans = dp[i+1][j][hasSo][1] + m[i] + f[i];
if(isEmpty[i] && j > 0) {
ans = min(ans, dp[i+1][j-1][1][hasUm]);
}
if(!isEmpty[i]) {
int k = min(j, m[i]);
ans = min(ans, dp[i+1][j-k][1][hasUm] + m[i] + m[i] - k);
}
}
}
}
}
cout << dp[0][empt][0][0] << endl;
}kkk
#include <bits/stdc++.h>
#define N 3003
#define INF 1000000007
using namespace std;
int n, f[N];
struct pool { int m, f; } p[N];
bool cmp1(pool x, pool y) { return x.m + x.f > y.m + y.f; }
bool cmp2(pool x, pool y) { return x.f - x.m > y.f - y.m; }
int main()
{
scanf("%d", &n);
int m = 0;
bool flag = 1;
for(int i = 1; i <= n; ++ i)
{
scanf("%d%d", &p[i].m, &p[i].f);
if(!p[i].m && !p[i].f) ++ m;
if(p[i].m) flag = 0;
}
if(flag) { puts("0"); return 0; }
sort(p + 1, p + n + 1, cmp1);
n -= m;
int sum = 0;
for(int i = 1; i <= n; ++ i) sum += p[i].m + p[i].f - 1;
if(!m)
{
sort(p + 1, p + n + 1, cmp2);
sum -= p[1].f - 1 - p[1].m;
for(int i = 2; i < n; ++ i)
if(p[i].f - 1 - p[i].m >= 0) sum -= p[i].f - 1 - p[i].m;
printf("%d\n", sum);
return 0;
}
for(int i = 1; i <= n; ++ i)
for(int j = m; j >= p[i].m; -- j) f[j] = max(f[j], f[j - p[i].m] + p[i].f - 1);
int ans = sum - f[m];
sum -= m;
int k = 0;
for(int i = 1; i <= n; ++ i)
if(p[i].f - 1 - p[i].m >= 0) sum -= p[i].f - 1 - p[i].m, k += p[i].m;
if(k >= m) ans = min(ans, sum);
else
{
f[0] = 0;
for(int i = 1; i <= m; ++ i) f[i] = -INF;
for(int i = 1; i <= n; ++ i) if(p[i].f - 1 - p[i].m < 0)
{
for(int j = m; j >= 0 && j + p[i].m >= m; -- j) ans = min(ans, sum - f[j] - (p[i].f - 1 - p[i].m));
for(int j = m; j >= p[i].m; -- j) f[j] = max(f[j], f[j - p[i].m] + p[i].f - 1 - p[i].m);
}
}
printf("%d\n", ans);
return 0;
}
京公网安备 11010502036488号