牛客编程S1-第七场题解

比赛地址
1.牛牛打怪兽

题意
身为屯里第一剑士的牛牛来到训练场里闯关,由于过于勤奋,牛牛的宝剑的耐久度降到了 22 ,这意味着牛牛最多只能打倒两只怪兽,否则将会被淘汰。

训练场的地图可以看作一棵以 11 为根节点的树,训练场的终点为这棵树的叶子结点,树上的每个结点最多有一只怪兽,结点与结点间的边上没有怪兽。

每一个有怪兽的结点上牛牛都需要打倒怪兽才算安全,并且牛牛一旦选定好打怪路线之后便不能走回头路。

请问牛牛有多少种到达终点且不被淘汰的路径。

牛客编程S1-第七场题解_第1张图片牛客编程S1-第七场题解_第2张图片

思路:dfs求解即可,要特判一下n为1的情况;

class Solution {
public:
    int sum;
    void dfs(vector<vector<int>>& g,vector<int>& f,int ans,int x,int fa){
        
        if(f[x-1]) ans--;
        if(ans<0) return;
        if(g[x].size()==1&&g[x][0]==fa){
            if(ans>=0) sum++;
            return;
        }
        for(int i=0;i<g[x].size();i++){
            if(g[x][i]==fa) continue;
            dfs(g,f,ans,g[x][i],x);
        }
    }
    int solve(int n, vector<Point>& Edge, vector<int>& f) {
        sum=0;
        vector<vector<int>> g(100005);
        if(n==1) return 1;
        for(int i=0;i<n-1;i++){
            g[Edge[i].x].push_back(Edge[i].y);
            g[Edge[i].y].push_back(Edge[i].x);
        }
        dfs(g,f,2,1,0);
        return sum;
        
    }
};

2.牛牛的冰激凌
牛牛公司老板让牛牛负责m个冰激凌的运输。运输车的冷库只够装n个冰激凌,一次运输需要t分钟,返回也需要t分钟。每个冰激凌制作好有一个时间。牛牛想知道最短运输完所有冰激凌的时间,以及在时间最短的情况下最少运输次数。

牛客编程S1-第七场题解_第3张图片
思路:设f[i]表示第i个运算完成的最短时间,d[i]为第i个运输完成最短时间对应的运送次数
当运第i个时候,他可以与前面n-1个一起运,故我们可以枚举与前面几个一起运算,若与前面k个一起运算则max(f[i-k]+k,c[i])计算出开始运算的时间,因为很有可能当已经返回,但是还没做出来,或者做出来了还没有返回,最后再加个k,及为该情况下第i个的运送时间,再跟新即可。

class Solution {
public:
    /**
     * 两个数表示答案
     * @param n int整型 一次运输的冰激凌数量
     * @param m int整型 总冰激凌数
     * @param t int整型 一次运输的时间
     * @param c int整型一维数组 表示每个冰激凌制作好时间<1e4
     * @param cLen int c数组长度
     * @return int整型vector
     */
    vector<int> icecream(int n, int m, int t, int* c, int cLen) {
        vector<int> solve;
        sort(c,c+m);
        int d[2010];
        int f[2010];
        memset(d,0x3f,sizeof(d));
        memset(f,0x3f,sizeof(f));
        d[0]=0;
        f[0]=-t;
        for(int i=1;i<=m;i++){
            for(int j=1;j<=min(n,i);j++){//枚举该冰激凌与前面几个一起运
                int val=max(f[i-j]+t,c[i-1])+t;
                int t=d[i-j]+1;
                if(val<=f[i]){
                    if(val<f[i]){//时间更少的话直接改变次数
                        d[i]=t;
                        f[i]=val;
                    }
                    else{//有可能相同时间但次数更少
                        d[i]=min(d[i],t);
                    }
                }
            }
        }
        solve.push_back(f[m]);
        solve.push_back(d[m]);
        return solve;
    }
};

3.数列求值

牛客编程S1-第七场题解_第4张图片

与该题类似的,大佬讲得很好

	class Matrix{
		public:
		Matrix(){
			Mat[0][0]=0;
            Mat[0][1]=0;
            Mat[1][0]=0;
            Mat[1][1]=0;
		}
		long long Mat[2][2];
		Matrix operator *(Matrix& a){
			Matrix ans;
			for(int i=0;i<2;i++){
				for(int j=0;j<2;j++){
					for(int k=0;k<2;k++){
						ans.Mat[i][j]=(ans.Mat[i][j]+Mat[i][k]*a.Mat[k][j])%1000000007;
					}
				}
			}
			return ans;
		}
	};
class Solution {
public:
	Matrix base;
	Matrix qmi(long long x){
		Matrix cnt;
		cnt.Mat[0][0]=1;
		cnt.Mat[1][1]=1;
		while(x){
			if(x&1) cnt=cnt*base;
			base=base*base;
			x>>=1;
		}
		return cnt;
	}
	
    long long nthElement(long long n, long long b, long long c) {
		base.Mat[0][0]=b;
		base.Mat[1][0]=c;
		base.Mat[0][1]=1;
		base.Mat[1][1]=0;
		Matrix temp=qmi(n-1);
		Matrix k;
		k.Mat[0][0]=1;
        /*for(int i=0;i<2;i++){
            for(int j=0;j<2;j++){
                cout<
		k=k*temp;
		return k.Mat[0][0];
    }
};

你可能感兴趣的:(牛客刷题)