NEVER,NEVER,NEVER have a=2b
in an array!
You have an array P , and each element is denoted as p1,p2…pn. Now
you can take any two numbers a and b from it. If a=2×bis satisfied, this array is a “bad array”.
Now you need to delete some elements from this array to make it is not “bad array”. Please output an integer indicating the minimum
number of the elements deleted. InputThe first line contains a positive integer n(1≤n≤105)
indicates the length of the array.
The next line contains n positive integers separated by spaces
pi(1≤pi≤106)Represents each element in the array. Output
Output an integer on a line to indicate the answer. Example Input 5 1 2 4 3 6 Output 2
Note
Deleting 2 and 3 or 2 and 6 can make the situation a=2×b is not occurring in the array.
思路
TAG: 动态规划
一种略麻烦的写法是先预处理出每一条链,然后对链做DP。
但是实际上因为值域只有1e6,所以只对值域做一个DP即可。
然后对于所有i*2>1e6的数字计算答案即可。
#include<iostream>
#include<stdio.h>
#include<math.h>
#include<string>
#include<string.h>
#include<algorithm>
#include<vector>
#include<assert.h>
using namespace std;
#define ll long long
const int maxn = 1e6+10;
int n;
int a[maxn],dp[maxn][2];
int ans;
int main()
{
scanf("%d",&n);
int x;
while(n--)
{
scanf("%d",&x);
a[x]++;
}
for(int i=1;i<=1000000;i++)
{
if(i%2==0)//如果i是偶数
{
dp[i][1]=dp[i/2][0];//如果这个数不删除 那么前一个数必须要删除 且删除的数量等于前一个数
dp[i][0]=min(dp[i/2][0],dp[i/2][1])+a[i];
//如果删除这个数字 则取前一个数的较小数并且加上这个数要删除的数量
}
else//如果是奇数
{
dp[i][0]=a[i];//删掉
dp[i][1]=0;//不删
}
}
for(int i=1;i<=1000000;i++)
{
if(i*2>1000000)ans+=min(dp[i][0],dp[i][1]);
}
printf("%d",ans);
return 0;
}