https://atcoder.jp/contests/abc219/tasks/abc219_d
第一眼看出是一道动态规划,只不过限制状态有两层
f[i][j][k]表示前i个物品第一个约束条件取j个第二个约束条件取k个的最小方案
然后可以仿照背包问题将i那一维给删掉,其实删不删空间都够
状态转移方程:
注意这里是至少,因此转移方程为
f
[
j
]
[
k
]
=
m
i
n
(
f
[
j
]
[
k
]
,
f
[
m
a
x
(
0
,
j
−
a
[
i
]
.
x
)
]
[
m
a
x
(
0
,
k
−
a
[
i
]
.
y
)
]
+
1
)
f[j][k]=min(f[j][k],f[max(0,j-a[i].x)][max(0,k-a[i].y)]+1)
f[j][k]=min(f[j][k],f[max(0,j−a[i].x)][max(0,k−a[i].y)]+1)
#include<unordered_set>
#include<unordered_map>
#include<algorithm>
#include<functional>
#include<string.h>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<vector>
#include<queue>
#include<stack>
#include<cmath>
#include<map>
#define fastcall __attribute__((optimize("-O3")))
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize("Ofast")
#pragma GCC optimize("inline")
#pragma GCC optimize("-fgcse")
#pragma GCC optimize("-fgcse-lm")
#pragma GCC optimize("-fipa-sra")
#pragma GCC optimize("-ftree-pre")
#pragma GCC optimize("-ftree-vrp")
#pragma GCC optimize("-fpeephole2")
#pragma GCC optimize("-ffast-math")
#pragma GCC optimize("-fsched-spec")
#pragma GCC optimize("unroll-loops")
#pragma GCC optimize("-falign-jumps")
#pragma GCC optimize("-falign-loops")
#pragma GCC optimize("-falign-labels")
#pragma GCC optimize("-fdevirtualize")
#pragma GCC optimize("-fcaller-saves")
#pragma GCC optimize("-fcrossjumping")
#pragma GCC optimize("-fthread-jumps")
#pragma GCC optimize("-funroll-loops")
#pragma GCC optimize("-freorder-blocks")
#pragma GCC optimize("-fschedule-insns")
#pragma GCC optimize("inline-functions")
#pragma GCC optimize("-ftree-tail-merge")
#pragma GCC optimize("-fschedule-insns2")
#pragma GCC optimize("-fstrict-aliasing")
#pragma GCC optimize("-falign-functions")
#pragma GCC optimize("-fcse-follow-jumps")
#pragma GCC optimize("-fsched-interblock")
#pragma GCC optimize("-fpartial-inlining")
#pragma GCC optimize("no-stack-protector")
#pragma GCC optimize("-freorder-functions")
#pragma GCC optimize("-findirect-inlining")
#pragma GCC optimize("-fhoist-adjacent-loads")
#pragma GCC optimize("-frerun-cse-after-loop")
#pragma GCC optimize("inline-small-functions")
#pragma GCC optimize("-finline-small-functions")
#pragma GCC optimize("-ftree-switch-conversion")
#pragma GCC optimize("-foptimize-sibling-calls")
#pragma GCC optimize("-fexpensive-optimizations")
#pragma GCC optimize("inline-functions-called-once")
#pragma GCC optimize("-fdelete-null-pointer-checks")
using namespace std;
//================================
#define debug(a) cout << #a": " << a << endl;
#define N 350
//================================
typedef pair<int,int> pii;
#define x first
#define y second
typedef long long LL; typedef unsigned long long ULL; typedef long double LD;
inline LL read() { LL s = 0, w = 1; char ch = getchar(); for (; !isdigit(ch); ch = getchar()) if (ch == '-') w = -1; for (; isdigit(ch); ch = getchar()) s = (s << 1) + (s << 3) + (ch ^ 48); return s * w; }
inline void print(LL x, int op = 10) { if (!x) { putchar('0'); if (op) putchar(op); return; } char F[40]; LL tmp = x > 0 ? x : -x; if (x < 0)putchar('-'); int cnt = 0; while (tmp > 0) { F[cnt++] = tmp % 10 + '0'; tmp /= 10; } while (cnt > 0)putchar(F[--cnt]); if (op) putchar(op); }
//=================================
int n;
int ft,sd;
pii a[N];
int sum1=0,sum2=0;
int f[N][N];
//=================================
int main(){
cin >> n;
cin >> ft >> sd;
for(int i=1;i<=n;i++){
cin >> a[i].x >> a[i].y;
sum1+=a[i].x,sum2+=a[i].y;
}
if(sum1<ft||sum2<sd) puts("-1");
else{
memset(f,0x3f,sizeof f);
f[0][0]=0;
for(int i=1;i<=n;i++)
for(int j=300;j>=0;j--)
for(int k=300;k>=0;k--){
f[j][k]=min(f[j][k],f[max(0,j-a[i].x)][max(0,k-a[i].y)]+1);
}
int ans=0x3f3f3f3f;
for(int i=ft;i<=300;i++)
for(int j=sd;j<=300;j++)
ans=min(ans,f[i][j]);
cout << ans << endl;
}
return 0;
}