思路:
首先要对乌龟的力量从小到大排序。于是dp[i, j]表示前i只乌龟叠j层所能达到的最小体重,不能叠j层则用INT_MAX表示。
有了这个转移方程的定义,问题一下子就变得明朗了,只能感叹自己关于动归的思路还是不够成熟。不知道如何变相思考问题。
dp[i, j] = min(dp[i-1, j], dp[i-1, j-1] + wi); 前提是i可以承载i-1
// #pragma comment(linker, "/STACK:1024000000,1024000000")
#include <iostream>
#include <algorithm>
#include <iomanip>
#include <sstream>
#include <string>
#include <stack>
#include <queue>
#include <deque>
#include <vector>
#include <map>
#include <set>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#include <limits.h>
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int,int> ii;
const int inf = 1 << 30;
const int INF = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
inline int Readint(){
char c = getchar();
while(!isdigit(c)) c = getchar();
int x = 0;
while(isdigit(c)){
x = x * 10 + c - '0';
c = getchar();
}
return x;
}
const int maxn=6600;
struct turtle{
int w,s;
bool operator < (const turtle& b)const{
return this->s < b.s;
}
}p[maxn];
int dp[maxn][maxn];
int main()
{
// freopen("in.txt","r",stdin);
// freopen("out.txt","w",stdout);
int tol=0;
int w,s;
while(scanf("%d%d",&w,&s)!=EOF){
p[++tol].w=w,p[tol].s=s;
}
sort(p+1,p+tol+1);
for (int i=0;i<=tol;i++){
dp[i][0]=0;
for (int j=1;j<=tol;j++)
dp[i][j]=inf;
}
for (int i=1;i<=tol;i++)
{
for (int j=1;j<=i;j++)
{
dp[i][j]=dp[i-1][j];
if (p[i].s-p[i].w >= dp[i-1][j-1] && dp[i-1][j-1] != inf)
dp[i][j]=min(dp[i][j],dp[i-1][j-1]+p[i].w);
}
}
int ans=0;
for (int i=tol;i>=1;--i){
if (dp[tol][i]!=inf){
ans=i;
break;
}
}
printf("%d\n",ans);
return 0;
}