zoukankan      html  css  js  c++  java
  • 9.15

    9.15

    (1)div——约数贡献

    真的是那天傻掉,,,

    好像想出了正解,,,

    反正挺简单

    就是把A的每个数约数小于n的存下来,然后sort一下统计。。。

    #include <queue>
    #include <cmath>
    #include <cstdio>
    #include <vector>
    #include <cstring>
    #include <utility>
    #include <iostream>
    #include <algorithm>
    
    using namespace std;
    const int N=1e7+5;
    inline int read() {
    	int x=0;char ch=getchar();
    	while(!isdigit(ch))ch=getchar();
    	while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();}
    	return x;
    }
    int n,m;
    int st[N],a,ans[205],top;
    int main() {
    	n=read();m=read();
    	for(int i=1,j;i<=m;i++) {
    		a=read();
    		j=1;
    		for(j=1;j*j<a&&j<=n;j++)
    			if(a%j==0) {
    				st[++top]=j;
    				if(a/j<=n) st[++top]=a/j;
    			}
    		if(j*j==a) st[++top]=j;
    	}
    	sort(st+1,st+1+top);
    	int len=1;
    	for(int i=2;i<=top+1;i++) {
    		if(st[i]==st[i-1]) len++;
    		else ans[len]++,len=1;
    	}
    	ans[0]=n;
    	for(int i=1;i<=m;i++)
    		ans[0]-=ans[i];
    	for(int i=0;i<=m;i++)
    		printf("%d
    ",ans[i]);
    	return 0;
    }
    
    

    (2)Market——另类背包

    给定(n)个物品,每个物品可以不选或选一个,第(i)个物品的价格为(c_i),价值为(v_i),出现时间为(t_i)。有(m)个询问,每次询问在出现时间不超过(T_i)的所有物品中选若干件,总花费不超过(M_i)的情况下,被选择物品的价值和的最大值是多少。(n≤ 300,m≤ 100000,ci,Mi ≤ 10^9,vi ≤ 300)

    我当时只会傻哈哈01dp,搞到50分

    #include <cstdio>
    #include <vector>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    
    using namespace std;
    const int N=305;
    inline int read() {
    	int x=0;char ch=getchar();
    	while(!isdigit(ch)) ch=getchar();
    	while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();}
    	return x;
    }
    inline void Max(int &x,int y){if(x<y)x=y;}
    int n,m;
    struct node{
    	int c,v,t;
    	bool operator < (const node &x) const {
    		return t==x.t?v>x.v:t<x.t;
    	}
    }p[N];
    int f[100005];
    int main() {
    	n=read();m=read();
    	for(int i=1;i<=n;i++) 
    		p[i].c=read(),p[i].v=read(),p[i].t=read();
    	sort(p+1,p+1+n);
    	int T,M,ans=0;
    	while(m--) {
    		T=read();M=read();ans=0;
    		for(int i=1;i<=n;i++) {
    			if(p[i].t>T) break;
    			for(int j=M;j>=p[i].c;j--)
    				Max(f[j],f[j-p[i].c]+p[i].v);			
    		}
    		for(int i=0;i<=M;i++)
    			Max(ans,f[i]),f[i]=0;
    		printf("%d
    ",ans);
    	}
    	return 0;
    }
    

    正解:

    先将物品时间升序排列,离线询问,即可去掉时间的限制。

    01背包,(c)(M)太大无法承受。
    考虑到(v_i)很小:记(f[j])为选出(j)的价值和的最小花费
    对于一个询问的答案就是:
    1、算出在(T_i)时间内所能购买的物品范围([1,x])
    2、二分答案满足(f[j]≤M_i)的最大(j)

    #include<bits/stdc++.h>
    #define int long long
    using namespace std;
    int n,m;
    int f[90010],sum[305];
    struct node{
    	int c,v,t;
    }e[305];
    int ans[100005];
    struct Node{
    	int m,id;
    	bool operator < (const Node &a) const{
    		return m>a.m;
    	}
    };
    vector<Node> s[305];
    bool cmp(node a,node b){
    	return a.t<b.t;
    }
    int read(){
    	int f=0,w=1;
    	char ch=getchar();
    	while(ch<'0'||ch>'9'){
    		if(ch=='-') w=-1;
    		ch=getchar();
    	}
    	while(ch>='0'&&ch<='9'){
    		f=f*10+ch-'0';
    		ch=getchar();
    	}
    	return f*w;
    }
    signed main(){
    	n=read(),m=read();
    	for(int i=1;i<=n;i++){
    		e[i].c=read(),e[i].v=read(),e[i].t=read();
    	}
    	sort(e+1,e+1+n,cmp);
    	for(int i=1;i<=n;i++){
    		sum[i]=sum[i-1]+e[i].v;
    	}
    	for(int i=1;i<=m;i++){
    		int x=read(),y=read();
    		int hd=1,tl=n,mid,pos;
    		while(hd<=tl){
    			mid=(hd+tl)/2;
    			if(x>=e[mid].t){
    				pos=mid;
    				hd=mid+1;
    			}
    			else tl=mid-1;
    		}
    		if(x>=e[1].t&&x<=e[n].t) s[pos].push_back((Node){y,i});
    		else if(x>e[n].t) s[n].push_back((Node){y,i});
    		else ans[i]=0;
    	}
    	memset(f,0x3f,sizeof(f));
    	f[0]=0;
    	for(int i=1;i<=n;i++){
    		for(int j=sum[i];j>=e[i].v;j--){
    			f[j]=min(f[j],f[j-e[i].v]+e[i].c);
    		}
    		if(s[i].size()>0){//保证单调 
    			sort(s[i].begin(),s[i].end());
    			int last=sum[i];
    			for(int j=0;j<s[i].size();j++){
    				for(int k=last;k>=0;k--){
    					if(f[k]<=s[i][j].m){
    						last=k;
    						ans[s[i][j].id]=k;
    						break;
    					}
    				}
    			}
    		}
    	}
    	for(int i=1;i<=m;i++)
    		cout<<ans[i]<<endl;
    	return 0;
    }
    

    孤岛营救问题

    这个和上面那个十分类似,这里用bfs实现

    #include <queue>
    #include <cstdio>
    #include <algorithm>
    #include <iostream>
    using namespace std;
    inline int read() {
    	int x=0,f=1;char ch=getchar();
    	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    	return f*x;
    }
    
    const int N=12;
    const int dx[]={1,-1,0,0},dy[]={0,0,1,-1};
    int n,m,e[N][N][N][N],cnt[N][N],key[N][N][N];
    bool vis[N][N][1<<14];
    struct node {
        int x,y,k,d;
        node(){}
        node(int _x,int _y,int _k,int _d) {
            x=_x,y=_y,k=_k,d=_d;
        }
    };
    
    int getkey(int x,int y) {
        int ans=0;
        for(int i=1;i<=cnt[x][y];++i) ans|=(1<<(key[x][y][i]-1));
        return ans;
    }
    queue <node> q;
    int bfs(int sx,int sy) {
        int sk=getkey(sx,sy);
        q.push(node(sx,sy,sk,0)),vis[sx][sy][sk]=1;
        while(!q.empty()) {
            node u=q.front(); q.pop();
            if(u.x==n&&u.y==m) return u.d;
            int ux=u.x,uy=u.y;
            for(int i=0;i<4;++i) {
                int vx=ux+dx[i],vy=uy+dy[i],opt=e[ux][uy][vx][vy];
                if(vx<1||vx>n||vy<1||vy>m||opt<0||(opt&&!(u.k&(1<<(opt-1))))) continue;
                int nxt=u.k|getkey(vx,vy);
                if(vis[vx][vy][nxt]) continue;
                q.push(node(vx,vy,nxt,u.d+1)),vis[vx][vy][nxt]=1;
            }
        }
        return -1;
    }
    int main() {
        int k,s,p;
        n=read();m=read();p=read();k=read();
        for(int i=1;i<=k;i++) {
    		int x1=read(),y1=read(),x2=read(),y2=read();
    		int g=read();
            if(g) e[x1][y1][x2][y2]=e[x2][y2][x1][y1]=g;
            else e[x1][y1][x2][y2]=e[x2][y2][x1][y1]=-1;
        }
    	s=read();
    	for(int i=1;i<=s;i++) {
    		int x=read(),y=read(),g=read();
            key[x][y][++cnt[x][y]]=g;
        }
        printf("%d
    ",bfs(1,1));
        return 0;
    }
    

  • 相关阅读:
    数据结构-树与二叉树-思维导图
    The last packet successfully received from the server was 2,272 milliseconds ago. The last packet sent successfully to the server was 2,258 milliseconds ago.
    idea连接mysql报错Server returns invalid timezone. Go to 'Advanced' tab and set 'serverTimezone' property
    redis学习笔记
    AJAX校验注册用户名是否存在
    AJAX学习笔记
    JSON学习笔记
    JQuery基础知识学习笔记
    Filter、Listener学习笔记
    三层架构学习笔记
  • 原文地址:https://www.cnblogs.com/ke-xin/p/13698903.html
Copyright © 2011-2022 走看看