不写做题思路,回头看,自己都看不懂了吧,作!
这么简单的一道题,竟然写了这么长时间,太不应该了。
而且n的范围是1e5,跑n^2竟然稍微处理一下也可以过去,而且加上一个排序,下面就写一下自己做题的思路,以及收获的成果。
首先,我感觉这题就是一个很简单的dp,动态规划,但是有一个点超时了。
ll perfect(ll n,ll m)
{
if(m==n) return 1;
if (m-n<=mm || n>m) return 0;
if (num[n]*p>=num[m])
{
mm = m-n+1;
return mm;
}
else return max(perfect(n+1,m),perfect(n,m-1));
}
这也合情合理,毕竟这个有很多的重复计算,然后我就考虑记忆化搜索,首先建立一个一维数组,以n为索引记录每一个值,但是遗憾的是,这样也不对。(上面的思路是:对于每个开始的n值,其对应的结果应该是一致的)。然后我又考虑开二维数组,这样的话,其实实际上也是跑O(n^2),并且开一个1e10的数组,也直接爆了,存不下这么多数据。
最后通过的方法竟是我最先放弃的一个暴力法,但是这个处理还是有点技巧的。
#include <bits/stdc++.h>
using namespace std;
//改成了dp 但是还是超时 看看有什么可以修改的地方 有没有重复计算
//应该是有的 对于每次的开头 结果都是固定的
typedef long long ll;
ll num[100006];
int main()
{
ll N,p;
cin >> N >> p;
for (int i = 0;i<N;i++)
{
scanf("%lld",&num[i]);
}
sort(num,num+N);
// printf("%lld",perfect(0,N-1));22分的做法
ll mmm = 0,ans = 0;
for(int i = 0;i<N;i++)
{
for (int j = i+ans;j<N;j++)
{
if (num[j] <= num[i] * p) {
mmm = j - i + 1;
} else break; //一旦不满足就退出内层循环
}
ans = max (ans,mmm);
}
if(ans==0) ans = 1;
cout << ans;
return 0;
}
首先就是那个for循环里面j的初始值,是先假设加上当前得出的最大数组长度,然后里面if的处理,我第一次是写错的,是2,5监测点,我猜测是因为有可能有重复数据的影响。
if (num[i]*p<num[j])
{
mm = j-i;
}
//错误的做法
总的来说,这题不难,但是卡了好久才过去。