zoukankan      html  css  js  c++  java
  • Leetcode 第 173 场周赛 题解(完结)

    Leetcode 第173场周赛 题解

    删除回文子序列

    因为该字符串仅有两字符构成,且删的是子序列,不要求连续,所以不难想到:

    1. 若为空串,则答案为 (0)

    2. 若为回文串,则答案为 (1)

    3. 否则,一定可以先把 (b) 字符构成的子序列删除,再把 (a) 字符构成的子序列删除,答案为 (2)

    时间复杂度 (O(n))

    typedef long long ll;
    typedef double db;
    #define _for(i,a,b) for(int i = (a);i < b;i ++)
    #define _rep(i,a,b) for(int i = (a);i > b;i --)
    #define INF 0x3f3f3f3f3f3f3f3f
    #define ZHUO 11100000007
    #define SHENZHUO 1000000007
    #define pb push_back
    #define debug() printf("Miku Check OK!
    ")
    #define maxn 200003
    #define X first
    #define Y second
    
    
    class Solution
    {
    public:
    	bool ispa(string s)
    	{
    		int sz = s.size();
            for(int i=0; i < sz ; i++)
    		{
    			if(s[i] != s[sz-i-1])
    			{
    				return false;
    			}
    		}
    		return true;
    	}
    	int removePalindromeSub(string s)
    	{
    		if(s.empty())
    			return 0;
    		if(ispa(s))
    			return 1;
    		return 2;
    	}
    };
    

    餐厅过滤器

    小模拟题,没啥好说的,注意最后的排序规则即可。

    时间复杂度 (O(nlogn))

    typedef long long ll;
    typedef double db;
    #define _for(i,a,b) for(int i = (a);i < b;i ++)
    #define _rep(i,a,b) for(int i = (a);i > b;i --)
    #define INF 0x3f3f3f3f3f3f3f3f
    #define ZHUO 11100000007
    #define SHENZHUO 1000000007
    #define pb push_back
    #define debug() printf("Miku Check OK!
    ")
    #define maxn 20003
    #define X first
    #define Y second
    
    
    struct res
    {
    	int id;
    	int rate;
    	int vf;
    	int pri;
    	int dis;
    	bool operator < (res b)
    	{
    		if(rate != b.rate)
                return rate > b.rate;
            return id > b.id;
    	}
    };
    class Solution
    {
    public:
    	vector<res> r;
    	vector<int> filterRestaurants(vector<vector<int>>& restaurants, int veganFriendly, int maxPrice, int maxDistance)
    	{
    		int a = veganFriendly;
    		int b = maxPrice;
    		int c = maxDistance;
    		vector<vector<int>> in = restaurants;
    		_for(i,0,in.size())
    		{
    			if(a==0 || a==1 && in[i][2]==1)
    			{
    				if(in[i][3]<=b && in[i][4]<=c)
    					r.pb({in[i][0],in[i][1],in[i][2],in[i][3],in[i][4]});
    			}
    		}
    		sort(r.begin(),r.end());
    		vector<int> rnt;
    		_for(i,0,r.size())
    			rnt.pb(r[i].id);
    		return rnt;
    		
    	}
    };
    

    阈值距离内邻居最少的城市

    建图,每个点跑一遍单源最短路,我用的是优先队列(Dij) 。然后遍历所有点,超过阈值就 (++) ,最后统计一下最少的就行。

    时间复杂度 (O(n^2logn))

    typedef long long ll;
    typedef double db;
    #define _for(i,a,b) for(int i = (a);i < b;i ++)
    #define _rep(i,a,b) for(int i = (a);i > b;i --)
    #define INF 0x3f3f3f3f3f3f3f3f
    #define ZHUO 11100000007
    #define SHENZHUO 1000000007
    #define pb push_back
    #define debug() printf("Miku Check OK!
    ")
    #define maxn 1003
    #define X first
    #define Y second
    
    //最大点数
    #define maxn 1003
    //最大边数
    #define maxe 20003
    
    class Solution
    {
        public:
        struct G
        {
            int n,m;
            int Next[maxe];
            int head[maxn];
            int ver[maxe];
            int val[maxe];
            int tot;
            void add(int x,int y,int w)
            {
                ver[++tot] = y,Next[tot] = head[x],head[x] = tot,val[tot] = w;
            }
    } g;
        struct Dij
        {
            typedef pair<int,int> P;
            ll d[maxn];
            int vis[maxn];
            priority_queue<P,vector<P>,greater<P>> q;
            int s;
            void dij(int s,const G &g)
            {
                _for(i,1,g.n+1)
                    d[i] = INF;
                memset(vis,0,sizeof(vis));
                d[s] = 0;
                q.push(P {0,s});
                while(!q.empty())
                {
                    P p = q.top();
                    q.pop();
                    int x = p.second;
                    if(vis[x]) continue;
                    vis[x] = 1;
                    for(int i = g.head[x]; i; i = g.Next[i])
                    {
                        int y = g.ver[i];
                        int w = g.val[i];
                        if(d[y] > d[x] + w)
                        {
                            d[y] = d[x] + w;
                            q.push(P {d[y],y});
                        }
                    }
                }
            }
        } d1;
    	int findTheCity(int n, vector<vector<int>>& edges, int distanceThreshold)
    	{
    		g.n = n;
            _for(i,0,edges.size())
    		{
    			g.add(edges[i][0]+1,edges[i][1]+1,edges[i][2]);
    			g.add(edges[i][1]+1,edges[i][0]+1,edges[i][2]);
    		}
    		int rnt = 0;
    		int mintimes = INT_MAX;
    		_for(i,0,n)
    		{
    			d1.dij(i+1,g);
    			int tmptimes = 0;
    			_for(j,0,n)
    				if(d1.d[j+1]<=distanceThreshold)
    					tmptimes ++;
    			if(tmptimes <= mintimes)
    				mintimes = tmptimes,rnt = i;
    		}
    		return rnt;
    	}
    };
    

    工作计划的最低难度

    想完成第 (i) ,就要完成第 (j(0≤j < i)) ,也就是需要依次完成,问题可转化为对数组进行划分,每个子数组的最大值的和的最小值问题。 最多可以划分 (jobDifficulty.size()) 块,特判一下能否划分。

    然后观察到每个工作和当前已划分敲定,则最小难度敲定,且满足最优子结构性可以由小问题转化为大问题,故设 (dp[i][j]) 表示对于已进行 (i) 个划分,当前已做到任务 (j) 时的最小花费。有 (dp) 转移方程如下

    (dp[i][j]=min(dp[i][j],dp[i-1][k]+maxx[k+1][j])(0≤k≤j-1))

    也就是说,当前想进行新的划分,划分完就划分了 (i) 次,所以由划分数 (i-1) 转移而来。其中数组 (maxx[i][j]) 的意思是数组 (jobDifficulty) 下标为 从 (i)(j) 的最大值,也就是要加上这次划分所产生的新花费。

    初始状态 (dp[0][0]:=0) 表示还没开始遍历数组时的 (0) 次划分,自然代价是 (0) 。目标是 (dp[d][jobDifficulty.size()]) ,代表遍历到最后一个元素且有 (d) 次划分。

    注意下标,时间复杂度 (O(dn^2))

    typedef long long ll;
    typedef double db;
    #define _for(i,a,b) for(int i = (a);i < b;i ++)
    #define _rep(i,a,b) for(int i = (a);i > b;i --)
    #define INF 0x3f3f3f3f
    #define ZHUO 11100000007
    #define SHENZHUO 1000000007
    #define pb push_back
    #define debug() printf("Miku Check OK!
    ")
    #define maxn 1003
    #define X first
    #define Y second
    
    class Solution
    {
    public:
    	vector<int> a;
    	int rnt = INT_MAX;
    	int dp[20][500];
    	int maxx[500][500];
    	int minDifficulty(vector<int>& jobDifficulty, int d)
    	{
    		a.pb(39);
    		_for(i,0,jobDifficulty.size())
    			a.pb(jobDifficulty[i]);
    		int sz = a.size();
    		if(d > sz-1)
    			return -1;
    			
    		_for(i,1,sz)
    		{
    			int maxnow = a[i];
    			_for(j,i,sz)
    			{
    				maxnow = max(maxnow,a[j]);
    				maxx[i][j] = maxnow;
    			}
    		}
    		
    		memset(dp,INF,sizeof(dp));
    		dp[0][0] = 0;
    
    		_for(i,1,d+1)
    			_for(j,1,sz)
    				_for(k,0,j)
    					dp[i][j] = min(dp[i][j],dp[i-1][k]+maxx[k+1][j]);
    		
    		return dp[d][sz-1];
    	}
    };
    
  • 相关阅读:
    SqlServer同义词
    Topshelf+Quartz3.0基于控制台应用程序快速开发可调度windows服务
    IdentityServer4实现.Net Core API接口权限认证(快速入门)
    记SqlSugar ORM框架之找不到主键问题
    Ocelot网关+IdentityServer4实现API权限认证
    Asp.Net Core入门之静态文件
    Asp.Net Core入门之自定义中间件
    Asp.Net Core入门之配置文件
    写在前面
    Web中间件常见漏洞总结
  • 原文地址:https://www.cnblogs.com/Asurudo/p/12234095.html
Copyright © 2011-2022 走看看