2.第k个数-----简单二分
题目链接
要找矩阵中的第k个数,暴力思想是枚举每一行,把每一行小于答案的数统计出来,因为a[i][j]=i*j
每一行都单调递增,所以可以用二分
#include <iostream>
using namespace std;
#define int long long
const int N = 100010;
int n,m,k;
bool check(int mid)
{
int res=0;
for(int i=1;i<=n;i++)
res+=min(m,mid/i);
return res>=k;
}
signed main()
{
cin>>n>>m>>k;
int l=1,r=m*n;
while(l<r)
{
int mid=l+r>>1;
if(check(mid))r=mid;
else l=mid+1;
}
cout<<r<<endl;
}
3.选数----二维费用01背包问题
题目链接
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 210,M = 5010;
#define int long long
int f[N][M];
int v[N],w[N];
int n,m;
signed main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
{
int x;
cin>>x;
while(x%5==0)x/=5,v[i]++;
while(x%2==0)x/=2,w[i]++;
}
memset(f,-0x3f,sizeof f);
f[0][0]=0;
for(int i=1;i<=n;i++)
{
for(int j=m;j>0;j--)
{
for(int k=25*i;k>=v[i];k--)
{
f[j][k]=max(f[j][k],f[j-1][k-v[i]]+w[i]);
}
}
}
int res=0;
for(int i=1;i<M;i++)
res=max(res,min(f[m][i],i));
cout<<res<<endl;
}