目录
动态规划:
nums=【1,5,2,4,3】找出最长的递增的子序列
eg.1 、2、 3或者1、 2、 4
找出最长的递增的子序列的长度:
暴力枚举(暴力搜索)
eg.
从1出发,可以选择5、 2、 4 、3
假如第二个数字选5,则其他的无法选择,最长长度为2
假如第二个数字选2,则可以选择3、 4,最长长度为3
……
直到子序列遍历完,并且需要实时记录当前最长的子序列长度
代码实现
时间复杂度:假设数组的个数为n,则存在2^n个子序列,每个子序列都要遍历一遍即
O(n*2^n)
记忆化搜索(通过哈希表或字典保存结果)——递归树的剪枝
非递归、迭代算法
题目理解:
示例中表示有10个用户,其中有两个1,两个4,两个2,两个8,一个5,一个7
当系统在一场对局中匹配不起来时,即1、4、2、8、5、7在线,另外的1、4、2、8不在线时,此时最多有6名用户无法匹配
第一种方法
分析:
①当k的值不等于0时,总人数-可以匹配的人就是最多无法匹配的情况
eg.k=4 ,用户积分为1,2,3,3,4,5,6
可匹配:(1,5)(2,6)
则保留1、2或者5 、6
7-2=5……最多5人无法匹配
②当k的值等于0时,且此时能匹配的人数>=3,总人数-积分相同的人数+相同的数字数量
eg.k=0, 用户积分为11115
5-4+1=2……最多两人
难点:考虑到k=0的情况
思路:
代码:
运行超时了……
#include <iostream>
using namespace std;
// 存储一个大数用来表示用户人数的存储空间
const int MAX=100000;
int count[MAX];
int main()
{
int n,k,maxn=0;
// n代表用户人数,k代表相差k个积分匹配,maxn最大积分
cin>>n>>k;
// for循环遍历所有数组
for(int i=0;i<n;i++)
{
int temp;
cin>>temp;
count[temp]++;
maxn=maxn>temp?maxn:temp;
}
int match=0;
for(int i=0;i+k<=maxn;i++)
{
while(k&&count[i]&&count[i+k])
{
match++;
count[i]--;
count[i+k]--;
}
while(!k&&count[i]>=2)
{
match+=count[i]-1;
count[i]=1;
}
}
cout << n-match << endl;
return 0;
}
第二种方法
思路:(动态规划)
①确定dp数组的定义:
dp[i] 表示选择前i个积分能获得的最大用户人数
②递推公式
题目理解:
eg.
n=10 k=1
示例:2 1 1 1 1 4 4 3 4 4
dp[0]=5
dp[1]=9
dp[2]=9
dp[3]=9
注意:
main函数需要返回0
放弃一下,明天再看