AtCoder Beginner Contest 219 D - Strange Lunchbox

https://atcoder.jp/contests/abc219/tasks/abc219_dAtCoder Beginner Contest 219 D - Strange Lunchbox_第1张图片

第一眼看出是一道动态规划,只不过限制状态有两层
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,ja[i].x)][max(0,ka[i].y)]+1)

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

你可能感兴趣的:(AtCoder,动态规划,动态规划)