首页 > 其他分享 >day2

day2

时间:2023-01-01 22:57:05浏览次数:55  
标签:dui int day2 unsigned long cnt2 include

今天是在学习折半搜索。
洛谷P4799
1.直接搜,比较简单的搜索,但只能过前两个子任务。

#include<iostream>
#include<algorithm>
using namespace std;
int n;
long long m;
long long a[50];
bool cmp(long long x,long long y){
	return x<y;
}
long long dfs(int x,long long y){
	if(x==n){
		return 1;
	}
	long long ans=1;
	for(int i=x+1;a[i]+y<=m&&i<=n;i++){
		ans=ans+dfs(i,y+a[i]);
	}
	return ans;
}
int main(){
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		cin>>a[i];
	}
	sort(a+1,a+n+1,cmp);
	cout<<dfs(0,0);
	return 0;
} 

2.背包dp,可过1,3两个子任务。

#include<iostream>
using namespace std;
int n;
long long m;
long long a[1000010];
long long f[1000010];
int main(){
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		cin>>a[i];
	}
	f[0]=1;
	for(int i=1;i<=n;i++){
		for(int j=m;j>=a[i];j--){
			f[j]+=f[j-a[i]];
		}
	}
	long long ans=0;
	for(int j=0;j<=m;j++){
		ans+=f[j];
	}
	cout<<ans;
	return 0;
}

3但第二个子任务背包dp空间不可行,考虑day1的对dp的多余状态的优化,unordered_map,可过1,2,3三个子任务。

#include<iostream>
#include<algorithm>
#include<unordered_map>
using namespace std;
int n;
long long m;
long long a[50];
long long dui[10000010];
long long b[10000010];
int cnt2=0;
long long c[10000010];
int cnt=0; 
bool cmp(long long x,long long y){
	return x<y;
}
bool cnp(long long x,long long y){
	return x>y;
}
unordered_map<long long ,long long> f;
int main(){
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		cin>>a[i];
	}
	sort(a+1,a+n+1,cnp);
	f[0]=1;
	dui[++cnt]=0;
	for(int i=1;i<=n;i++){
		for(int j=cnt;j>=1;j--){
			c[cnt-j+1]=dui[j];
		}
		int l=0,r=cnt;
		while(l<r){
			int mid=(l+r+1)/2;
			if(a[i]+dui[mid]>m){
				r=mid-1;
			}
			else{
				l=mid;
			}
		}
		cnt2=0;
		for(int j=l;j>=1;j--){
			if(f[dui[j]+a[i]]==0){
				b[++cnt2]=dui[j]+a[i];
			}
			f[dui[j]+a[i]]+=f[dui[j]];
		}
		int cnt1=cnt;
		int j=cnt1,k=cnt2;
		cnt=0;
		while(j>=1||k>=1){
			if(j<1){
				dui[++cnt]=b[k];
				k--;
				continue;
			}
			if(k<1){
				dui[++cnt]=c[j];
				j--;
				continue;
			}
			if(c[j]<b[k]){
				dui[++cnt]=c[j];
				j--;
			}
			else{
				dui[++cnt]=b[k];
				k--;
			}
		}
	}
	long long ans=0;
	for(int i=1;i<=cnt;i++){
		ans+=f[dui[i]];
	}
	cout<<ans;
	return 0;
}

4.考虑我们只需要知道总方案数是多少,并不需要知道各个状态的方案数是多少,第四个子任务n<=40,将它折半,就是两个第二个子任务,每个第二个子任务的状态数最多是2^n个,这样对两个第二个子任务分别按状态大小排序,前缀和加双指针,在第二个子任务中用map记录每个状态的方案数。

#include<iostream>
#include<algorithm>
#include<unordered_map>
using namespace std;
unsigned int n;
unsigned long long m;
unsigned long long a[50];
unordered_map<unsigned long long,unsigned long long>mp1;
unordered_map<unsigned long long,unsigned long long>mp2;
unsigned long long dui1[1100010];
unsigned int cnt1=0;
unsigned long long dui2[1100010];
unsigned int cnt2=0;
inline void dfs1(unsigned int x,unsigned long long y){
	if(x==n){
		return ;
	}
	for(int i=x+1;a[i]+y<=m&&i<=n;i++){
		if(mp1[y+a[i]]==0){
			dui1[++cnt1]=y+a[i];
		}
		mp1[y+a[i]]++;
		if(y+a[i]<m)dfs1(i,y+a[i]);
	}
}
inline void dfs2(unsigned int x,unsigned long long y){
	if(x==n){
		return ;
	}
	for(int i=x+1;a[i]+y<=m&&i<=n;i++){
		if(mp2[y+a[i]]==0){
			dui2[++cnt2]=y+a[i];
		}
		mp2[y+a[i]]++;
		if(y+a[i]<m)dfs2(i,y+a[i]);
	}
}
inline bool cmp(unsigned long long x,unsigned long long y){
	return x<y;
}
unsigned long long qian[1100010];
int main(){
	cin>>n>>m;
	for(unsigned int i=1;i<=n;i++){
		cin>>a[i];
	}
	sort(a+1,a+n+1,cmp);
	dui2[++cnt2]=0;
	mp2[0]=1;
	dfs2(n/2,0);
	n/=2;
	dui1[++cnt1]=0;
	mp1[0]=1;
	dfs1(0,0);
	sort(dui1+1,dui1+cnt1+1,cmp);
	sort(dui2+1,dui2+cnt2+1,cmp);
	for(unsigned int j=1;j<=cnt2;j++){
		qian[j]=qian[j-1]+mp2[dui2[j]];
	}
	int j=cnt2;
	unsigned long long ans=0;
	for(unsigned int i=1;i<=cnt1&&j>0;i++){
		while(j>0&&dui2[j]+dui1[i]>m){
			j--;
		}
		if(j>0){
			ans+=mp1[dui1[i]]*qian[j];
		}
	}
	cout<<ans;
	return 0;
}

标签:dui,int,day2,unsigned,long,cnt2,include
From: https://www.cnblogs.com/z-2-we/p/17019199.html

相关文章

  • day2
    早上背墨墨背单词和钱老师的论文,现在论文查重阶段。下午学习数电找到了一个老师的课程,感觉挺不错的,第一遍先无倍速听一次。(到p3)晚上出去和妈妈吃了串串,开摩托车回......
  • 刷刷刷Day2| 977.有序数组的平方 ,209.长度最小的子数组 ,59.螺旋矩阵II
    977.有序数组的平方LeetCode题目要求给你一个按非递减顺序排序的整数数组nums,返回每个数字的平方组成的新数组,要求也按非递减顺序排序。示例1:输入:nums=[-4,-......
  • 代码随想录算法训练营Day2|977.有序数组的平方,209.长度最小的子数组,59.螺旋数组
    977.有序数组的平方题目链接:https://leetcode.cn/problems/squares-of-a-sorted-array/文章链接:https://programmercarl.com/0209.长度最小的子数组.html视频链接:https......
  • 超全面的JavaWeb笔记day23<AJAX>
    AJAXAJAX概述1什么是AJAXAJAX(AsynchronousJavascriptAndXML)翻译成中文就是“异步Javascript和XML”。即使用Javascript语言与服务器进行异步交互,传输的数据为XML(当然,传......
  • 重温C程序设计(第五版)-谭浩强-Day2
    1.字符输入输出函数:putchar(c)为一般形式注:putchar(‘\n’)为输出一个换行符,putchar为输出一个字符,不要用“”,这个使用来表示输出字符串的。字符类型也属于整数类型,因此将一个......
  • Day2:学习安装jdk
    Java基础卸载JDK删除java的安装目录删除JAVA_HOME删除path下关于的JAVA目录java-version安装JDK搜索JDK8,找到下载地址同意协议,下载电脑对应的版本双击安......
  • 代码随想录算法训练营Day24|77. 组合
    代码随想录算法训练营Day24|77.组合回溯基础回溯的本质是穷举,穷举所有可能,然后选出我们想要的答案,常见的问题类型为:组合问题:N个数里面按一定规则找出k个数的集合切割......
  • 代码随想录算法训练营Day25|216. 组合总和 III、17. 电话号码的字母组合
    代码随想录算法训练营Day25|216.组合总和III、17.电话号码的字母组合216.组合总和III216.组合总和III与「77.组合」类似,但区别在于题干要求的变化:只使用数字1......
  • comprehensive-rust day2 练习
    题目在这里pubfnprefix_matches(prefix:&str,request_path:&str)->bool{//splitbyslashandchangeelementintoOptionandaddNoneattheend.......
  • AT_jag2018summer_day2_a 10^N+7 题解
    题目传送门题目大意有三个非负整数$x,y,z$,找到符合以下条件的最小非负整数\(n\);$n\{\rm\mod}\10^1+7\=\x$$n\{\rm\mod}\10^2+7\=\y$$n\{\rm\mo......