zoukankan      html  css  js  c++  java
  • hgoi#20191103

    T1-繁繁的数字

    问将一个数分解成多个 $ 2 $ 的幂次相加的形式有多少种方案

    解法

    简单dp,依次用1,2,4,8...去转移即可
    复杂度是 $ n log n $ 的

    ac代码

    #include<bits/stdc++.h>
    #define mod 1000000007
    using namespace std;
    int n,f[1000010];
    int main()
    {
    	freopen("number.in","r",stdin);
    	freopen("number.out","w",stdout);
    	scanf("%d",&n),f[0]=1;
    	for(int i=0;;i++)
    	{
    		int k=(1<<i);
    		if(k>n)break;
    		for(int j=k;j<=n;j++)
    			(f[j]+=f[j-k])%=mod;
    	}
    	printf("%d
    ",f[n]);
    	return 0;
    }
    

    T2-繁繁的游戏

    你有一个简单的差分约束系统
    在一幅无向图中要求每条边两端的点的权值差不超过d
    问权值最大和权值最小的点的权值差是多少

    解法

    显然,最优的情况就是对于每个点跑最短路
    找它最远的点,所有这些最远的点中距离最远的就是答案

    ac代码

    #include<bits/stdc++.h>
    #define inf 0x3f3f3f3f
    #define pb push_back
    using namespace std;
    vector<int>e[100];
    queue<int>q;
    int T,n,d,ans,dis[100];
    char opt;
    int main()
    {
    	freopen("bridge.in","r",stdin);
    	freopen("bridge.out","w",stdout);
    	scanf("%d",&T);
    	while(T--)
    	{
    		scanf("%d%d",&n,&d),ans=0;
    		for(int i=1;i<=n;i++)
    		{
    			vector<int>().swap(e[i]);
    			for(int j=1;j<=n;j++)
    			{
    				for(opt=getchar();opt!='N'&&opt!='Y';opt=getchar());
    				if(opt=='Y')e[i].pb(j);
    			}
    		}
    		for(int i=1;i<=n;i++)
    		{
    			memset(dis,0x3f,sizeof(dis));
    			dis[i]=0,q.push(i);
    			while(!q.empty())
    			{
    				int u=q.front();q.pop();
    				for(auto v:e[u])
    					if(dis[v]==inf)
    						dis[v]=dis[u]+1,q.push(v);
    			}
    			for(int j=1;j<=n;j++)
    				ans=max(ans,dis[j]);
    		}
    		if(ans==inf)puts("-1");
    		else printf("%d
    ",ans*d);
    	}
    	return 0;
    }
    

    T3-繁繁的队列

    你有一个n的排列,每次你可以取一个数放到队首或队尾,问最少多少次操作可以将其变成升序

    解法

    我是不是在打假赛,这道题代码比T1还短emm
    显然我们不用动的只有一个值连续的上升子序列
    那么我们找出最长的值连续的上升子序列,其他的点都要进行一次操作

    ac代码

    #include<bits/stdc++.h>
    using namespace std;
    int n,x,ans,f[50010];
    int main()
    {
    	freopen("queue.in","r",stdin);
    	freopen("queue.out","w",stdout);
    	scanf("%d",&n);
    	for(int i=1;i<=n;i++)
    		scanf("%d",&x),
    		f[x]=f[x-1]+1,
    		ans=max(ans,f[x]);
    	printf("%d
    ",n-ans);
    	return 0;
    }
    
  • 相关阅读:
    poj2481 线段树(单点更新)
    二叉查找树 hdu(3791 && 3999)
    计算机科学32个最重要的算法
    03最小路径覆盖问题
    02太空飞行计划问题
    hdu 2448最短路+最佳匹配
    poj1419 最大团
    hdu 3585(二分+最大团)
    hdu 3622 2-SAT
    hdu3592差分约束
  • 原文地址:https://www.cnblogs.com/muronglin/p/hgoi-20191103.html
Copyright © 2011-2022 走看看