题意:n个箱子,每个箱子都有自己的承重和自重,它所承受的重量是承重-自重,问最多能叠几个箱子
题解:首先是承重大的一定在下面,可以证明承重大的在上面没有在下面的优,然后就是dp[i][j]代表前i个箱子碟j个的最小重量
状态转移:dp[i][j] = min(dp[i-1][j], dp[i-1][j-1]+r[i]);
#include <bits/stdc++.h> #define ll long long #define maxn 1010 #define INF 0x3f3f3f3f using namespace std; struct node{ int w, r; }a[maxn]; int cmp(node aa,node bb){ return aa.r<bb.r; } int dp[maxn][maxn]; int main(){ int T, n; scanf("%d", &T); while(T--){ memset(dp, INF, sizeof(dp)); scanf("%d", &n); for(int i=0;i<=n;i++) dp[i][0] = 0; for(int i=1;i<=n;i++) scanf("%d%d", &a[i].w, &a[i].r); sort(a+1, a+n+1, cmp); //dp[i][j]前i个箱子碟j个的最小重量 for(int i=1;i<=n;i++){ for(int j=1;j<=i;j++){ if(i>=j-1) dp[i][j] = dp[i-1][j]; if(dp[i][j] > dp[i-1][j-1]+a[i].w && a[i].r >= a[i].w+dp[i-1][j-1]) dp[i][j] = dp[i-1][j-1]+a[i].w; } } for(int i=n;i>=1;i--) if(dp[n][i]!=INF){ printf("%d ", i); break; } } return 0; }