f[i][j]表示前i个课程中有j个课程能不哭的最小和
之后在从n到0遍历一下,如果f[n][j]不为INF,那么说明这个地方有被赋值过,那么此时不哭的数量最大,直接break然后输出即可
#include <bits/stdc++.h>
using namespace std;
const int INF=0x3f3f3f3f;
const int maxn=4005;
int n;
int a[maxn],b[maxn];
int f[maxn][maxn];
int main()
{
memset(f,INF,sizeof(f));
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i]>>b[i];
f[0][0]=0;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=i;j++)
{
if(f[i-1][j-1]<=a[i]*(i-1))
f[i][j]=f[i-1][j-1]+a[i];
if(f[i-1][j-1]<=b[i]*(i-1))
f[i][j]=min(f[i][j],f[i-1][j-1]+b[i]);
f[i][j]=min(f[i][j],f[i-1][j]+min(a[i],b[i]));
}
}
int t;
for(int i=n;i>=0;i--)
if(f[n][i]!=INF)
{
t=i;
break;
}
cout<<n-t<<endl;
return 0;
}