Niu Ke Practice 69

It's the first time to hit Niu Ke directly. . .
y1s1 Niuke’s evaluation system is really slow, so I don’t want to pay

B-Division

Topic link
First, a[]greedy the array in reverse order to get val (i, j) = a 1 + a 2 +… + ai × j val(i,j)=a_1+a_2+\dots+a_(i×j)val(i,j)=a1+a2++ai×j
Try to prove: analysis shows that we will eventually choose i × ji × ji×a[]The number of j arrays. Greedy is sure to choose the bigger the better. Try the firstjj ofeach groupNumbers with large j are the firsti × ji × j in thearrayi×Subset of the number with large j , you can divide the original array intoiii × ji × jbeforeiparts are selectedi×j is big.

#include<iostream>
#include<algorithm>
using namespace std;
const int N=100010;
typedef long long ll;
ll a[N],s[N];
int n;
int x,y;
int main()
{
    
    
    cin>>n;
    for(int i=1;i<=n;i++) cin>>a[i];
    cin>>x>>y;
    sort(a+1,a+1+n);
    reverse(a+1,a+1+n);
    for(int i=1;i<=n;i++) s[i]=s[i-1]+a[i];
    ll res=0;
    for(int i=1;i<=x;i++)
        for(int j=1;j<=y;j++)
               res+=s[i*j];
    cout<<res<<endl;
    return 0;
}

C-travel

Topic link
For a connected graph, try to remove some edges, but in the end ensure that the graph is connected and the remaining edges are as large as possible. If we use kurskal to find the maximum spanning tree, it just meets the above requirements. We are looking for dist (u, v) dist(u,v)dist(u,v ) , only walking the edge on the maximum spanning tree can guaranteedist (u, v) dist(u,v)dist(u,v ) Maximum. When choosing a permutation, each edge must pass at least once, and the answer must not exceed the edge weight sum on the maximum spanning tree. Try to construct a solution such that the answer is equal to the sum of the edge weights on the maximum spanning tree: select the two points of the smallest edge in turn, and then delete this edge (meaning that the edge cannot be selected again), so that the structure can be constructed The best answer.

#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=500010;
struct node
{
    
    
    int a,b,w;
    bool operator <(const node& o)const
    {
    
    
        return w>o.w;
    }
}e[N];
int n,m;
int p[N];
int find(int x)
{
    
    
    return x==p[x]?x:p[x]=find(p[x]);
}
int main()
{
    
    
    cin>>n>>m;
    for(int i=0;i<m;i++) cin>>e[i].a>>e[i].b>>e[i].w;
    for(int i=1;i<=n;i++) p[i]=i;
    sort(e,e+m);
    ll res=0;
    for(int i=0;i<m;i++)
    {
    
    
        int a=e[i].a,b=e[i].b,w=e[i].w;
        int pa=find(a),pb=find(b);
        if(pa!=pb)
        {
    
    
            p[pa]=pb;
            res+=w;
        }
    }
    cout<<res<<endl;
    return 0;
}

After completing 2 questions, I found that Niuke’s thinking is still quite difficult. If you can draw a conclusion, it is still very easy to write code. In the future, you will have to practice this thinking + algorithm.

D-Matches line up

At first I thought it was a number theory scum. I didn’t want to look at number theory , but it was actually a dp
state representation: f [i] [j] [0/1] f[i][j][0/1]F [ I ] [ J ] [ 0 / . 1 ] represents the frontiii personal choicejjj increaseddd and uncheck/chooseiii Individual
state calculation:
f [i] [j] [0] = f [i − 1] [j] [0] + (a [i − 1] + d ≤ a [i]) f [i − 1] [j] [1] f [i] [j] [0] = f [i-1] [j] [0] + (a [i-1] + d \ leq a [i]) f [i- 1] [j] [1]f[i][j][0]=f[i1][j][0]+(a[i1]+da[i])f[i1][j][1]
f [ i ] [ j ] [ 1 ] = f [ i − 1 ] [ j − 1 ] [ 0 ] + f [ i − 1 ] [ j − 1 ] [ 1 ] f[i][j][1]=f[i-1][j-1][0]+f[i-1][j-1][1] f[i][j][1]=f[i1][j1][0]+f[i1][j1 ] [ 1 ] A
lot of dp probabilities are essentially calculating the number of plans, and then using factorial and inverse element to calculate the answer.

#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=5010;
const ll mod=998244353;
ll a[N],d;
ll f[2][N][2];// f[i][j][0/1] 表示对于前i个人选择j个增加d 并且不选/选择第i个人
int n;
ll fact[N],infact[N];
ll qmi(ll a,ll b,ll p)
{
    
    
    ll res=1;
    while(b)
    {
    
    
        if(b&1) res=res*a%p;
        a=a*a%mod;
        b>>=1;
    }
    return res;
}
void init(int n)
{
    
    
    fact[0]=infact[0]=1;
    for(int i=1;i<=n;i++)
    {
    
    
        fact[i]=fact[i-1]*i%mod;
        infact[i]=qmi(fact[i],mod-2,mod);
    }
}

int main()
{
    
    
    cin>>n>>d;
    init(n);
    for(int i=1;i<=n;i++) cin>>a[i];
    sort(a+1,a+1+n);
    f[0][0][0]=1;
    for(int i=1;i<=n;i++)
    {
    
    
        for(int j=0;j<=i;j++)
        {
    
    
            if(j) f[i&1][j][1]=(f[i-1&1][j-1][0]+f[i-1&1][j-1][1])%mod;
            f[i&1][j][0]=(f[i-1&1][j][0]+f[i-1&1][j][1]*(a[i-1]+d<=a[i]))%mod;
        }
    }
    for(int i=1;i<=n;i++)
    {
    
    
        ll res=((f[n&1][i][0]+f[n&1][i][1])%mod*fact[n-i]%mod*fact[i]%mod*infact[n]%mod+mod)%mod;
        cout<<res<<endl;
    }
}

Come on~

Guess you like

Origin blog.csdn.net/Fighting_Peter/article/details/108554410