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;
    }
    

  • 相关阅读:
    VFL使用
    深复制与浅复制&&strong,copy修饰符总结
    数组的三种查找方法
    开发技巧-代码块使用
    2 duplicate symbols for architecture“文件冲突”
    利用echarts画折线图圆饼
    tab栏切换2
    利用highcharts.js画圆饼
    tab切换
    file上传图片并展示
  • 原文地址:https://www.cnblogs.com/ke-xin/p/13698903.html
Copyright © 2011-2022 走看看