zoukankan      html  css  js  c++  java
  • 9.21

    9.21

    (1)sequence ——&和 | 的性质

    想到了

    越或肯定越大,越与一定不会变大,反而有可能变小;

    要求>=k个,所以或就是把所有的都或起来,与则是只与k个(没想到)

    想到了按位统计,但没想怎么快速的删除一个与——其实很简单 ,就[0,32]遍历一遍就行然后对应的减掉

    #include <queue>
    #include <cmath>
    #include <cstdio>
    #include <vector>
    #include <cstring>
    #include <utility>
    #include <iostream>
    #include <algorithm>
    
    using namespace std;
    const int N=1000005;
    const int M=33;
    inline int read() {
    	int x=0,f=1;char ch=getchar();
    	while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
    	while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();}
    	return f*x;
    }
    inline void Max(int &x,int y){if(x<y)x=y;}
    inline void Min(int &x,int y){if(x>y)x=y;}
    int n,k,a[N],ans1,ans2=0;
    int ct[N],b[N];
    int main() {
    //	freopen("sequence.in","r",stdin);
    //	freopen("my.out","w",stdout);
    	b[0]=1;
    	for(int i=1;i<M;i++) b[i]=b[i-1]*2;
    	
    	n=read();k=read();
    	for(int i=1;i<=n;i++) a[i]=read(),ans1|=a[i];
    	for(int i=1;i<=k;i++) 
    		for(int j=0;j<M;j++)
    			if((a[i]&b[j])==0) ct[j]++;
    	for(int j=0;j<M;j++) 
    		if(!ct[j]) ans2+=b[j];
    	for(int i=k+1;i<=n;i++) {
    		for(int j=0;j<M;j++) {
    			if((a[i-k]&b[j])==0) ct[j]--;
    			if((a[i]&b[j])==0) ct[j]++;
    		}
    		int mx=0;
    		for(int j=0;j<M;j++) 
    			if(!ct[j]) mx+=b[j];
    		ans2=max(mx,ans2);
    	}
    	printf("%d %d
    ",ans1,ans2);
    	return 0;
    }
    
    
    

    (2)gift——01 背包变形

    我们可以枚举现在没有选择的最小的数字编号是 i,那么这也就 说明 比p[i] 小的都被选择了。那么再枚举一个 j 表示还能选择比 j 小的数(按照原题来说就是还剩 j 块钱),那么 j 必须比 p [ i ] 小,不然的话就可以再选择 p[i]了——这里用背包

    设$$ f[i][j]$$表示选择了第 i 到第 n 个数字,和为 j 的方案数。

    (f[i][j] = f[i + 1][j] + f[i + 1][j − p[i]])

    #include <queue>
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    
    using namespace std;
    const int N=1100;
    const int P=1e7+7;
    inline int read() {
    	int x=0,f=1;char ch=getchar();
    	while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
    	while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();}
    	return f*x;
    }
    typedef long long LL;
    int n,m;
    int s[N],p[N];
    LL f[N][N],ans;
    int main() {
    	n=read();m=read();
    	for(int i=1;i<=n;i++) p[i]=read();
    	sort(p+1,p+1+n);
    	for(int i=1;i<=n;i++) s[i]=s[i-1]+p[i];
    	if(s[n]<m) {//Q1
    		printf("1
    ");return 0;
    	}
    	f[n+1][0]=1;
    	for(int i=n;i>=1;i--)
    		for(int j=0;j<=m;j++) 
    			if(j>=p[i]) f[i][j]=(f[i+1][j]+f[i+1][j-p[i]])%P;
    			else f[i][j]=f[i+1][j];
    	for(int i=1;i<=n;i++) 
    		for(int j=0;j<p[i];j++)
    			if(m-s[i-1]-j>=0)
    				ans=(ans+f[i+1][m-s[i-1]-j])%P;
    	printf("%lld
    ",ans);
    	return 0;
    }
    
    
    

    Q1 特判 : 如果所有加起来都没那么多钱那么只有一种方案——全买

  • 相关阅读:
    学习opencv跟轮廓相关的
    opencv 连通域需要的函数解析
    【7.4】__new__和__init__的区别
    【7.3】属性描述符和属性查找过程
    【7.2】__getattr__、__getattribute__魔法函数
    【7.1】property动态属性
    【6.4】一个经典的参数错误
    【6.3】del语句和垃圾回收
    【6.2】==和is的区别
    【6.1】python中的变量是什么
  • 原文地址:https://www.cnblogs.com/ke-xin/p/13781871.html
Copyright © 2011-2022 走看看