Codeforce 321DIV2 ABCD

来源:互联网 发布:对人工智能社会的畅想 编辑:程序博客网 时间:2024/05/16 14:54

A.

题意:找到一个最长上升序列。

解法:最最最最暴力。。

#include <bits/stdc++.h>


#define LOCAL
#define ll  long long
#define lll unsigned long long
#define MAX 1000009
#define eps 1e-8
#define INF 0x7fffffff
#define mod 1000000007


using namespace std;


int a[MAX];


int main()
{


    int n;
    cin>>n;
    int sum = 1;
    int _max = -1;
    cin>>a[0];
    int k = a[0];
    for(int i = 1;i<n;i++)
    {
        cin>>a[i];
        if(a[i]>=k)
        {
            sum++;
        }
        else
        {
            _max = max(_max, sum);
            sum = 1;
        }
        k = a[i];
    }
    _max = max(_max, sum);
    cout<<_max<<endl;
    return 0;
}

B.

题意:找到任意元素之间绝对值小于d的集合的幸福值和的最大值。

解法:把m从小到大排序,然后二分查找 m[i] 和 m[i] + d - 1的位置,然后维护个前缀和,这样就能快速找到区间和了。

写的时候注意边界的处理


#include <bits/stdc++.h>


#define LOCAL
#define ll  long long
#define lll unsigned long long
#define MAX 1000009
#define eps 1e-8
#define INF 0x7fffffff
#define mod 1000000007


using namespace std;


struct node{
    ll m,s;
}p[MAX];
bool cmp(node a,node b)
{
    return a.m < b.m;
}
ll sum[MAX];
ll x[MAX];


int main()
{
    int n,d;
    while(~scanf("%d%d",&n,&d))
    {
        for(int i = 0;i<n;i++)
        {
            cin>>p[i].m>>p[i].s;
        }
        sort(p,p+n,cmp);
        sum[0] = p[0].s;
        for(int i = 1;i<n;i++)
        {
            sum[i] = sum[i - 1] + p[i].s;
        }
        for(int i = 0;i<n;i++)
        {
            x[i] = p[i].m;
        }
        ll _max = -1;
        for(int i = 0;i<n;i++)
        {
            int pos1 = lower_bound(x,x+n,p[i].m) - x;
            int pos2 = upper_bound(x,x+n,p[i].m + d - 1) - x;
            //cout<<pos1<<" "<<pos2 - 1<<endl;
            if(pos1==pos2-1)
            {
                _max = max(_max,p[pos1].s);
            }
            else
            {
                if(pos1 == 0)
                     _max = max(_max,sum[pos2 - 1]);
                else
                    _max = max(_max,sum[pos2 - 1] - sum[pos1 - 1]);
            }
        }
        printf("%lld\n",_max);
    }
    return 0;

C.

题意:实质是从根节点出发到叶子节点的路径上,最长连续被标记的长度小于等于d的叶子节点数

解法:DFS 三个参数 当前结点 当前节点的父亲节点 最长连续被标记的长度

没有被标记的就清空


#include <bits/stdc++.h>


#define LOCAL
#define ll  long long
#define lll unsigned long long
#define MAX 1000009
#define eps 1e-9
#define INF 0x7fffffff
#define mod 1000000007


using namespace std;


struct node
{
    int num;
    int to;
};
vector<int>g[MAX];
int vis[MAX];
int num[MAX];
int ans;
int n,d;


void dfs(int u,int sum,int fu)
{
   if(sum > d)
    return ;
   if(g[u].size()==1&&u!=1)
       ans++;
   for(int i = 0;i<g[u].size();i++)
   {
       int v = g[u][i];
       if(v==fu)continue;
       if(vis[v])
        dfs(v,sum+1,u);
       else
        dfs(v,0,u);
   }
}


int main()
{
    cin>>n>>d;
    memset(vis,0,sizeof(vis));
    for(int i = 1; i<=n; i++)
    {
        cin>>vis[i];
    }
    for(int i = 1; i<n; i++)
    {
        int u,v;
        cin>>u>>v;
        g[u].push_back(v);
        g[v].push_back(u);
    }
    ans = 0;
    dfs(1,vis[1],-1);
    printf("%d\n",ans);
    return 0;

D.

题意:n到菜选m道菜,且先选i 后选j 会额外得到 use[i][j]的奖励,求最大值

解法:状态压缩DP 第一维选取了哪些菜,第二维,最后一次选的菜是什么

#include <bits/stdc++.h>


#define LOCAL
#define ll  long long
#define lll unsigned long long
#define MAX 1000009
#define eps 1e-8
#define INF 0x7fffffff
#define mod 1000000007


using namespace std;


ll dp[1<<18][18];//第一维选取了哪些菜,第二维,最后一次选的菜是什么
ll a[50];
ll use[50][50];


int main()
{
    int n,m,k;
    ll u,v,w;
    while(~scanf("%d%d%d",&n,&m,&k))
    {
        for(int i = 0; i<n; i++) scanf("%lld",&a[i]);
        for(int i = 0; i<k; i++)
        {
            scanf("%lld%lld%lld",&u,&v,&w);
            --u;
            --v;
            use[u][v] = w;
        }
        for(int i = 0; i<n; i++)
        {
            dp[1<<i][i] = a[i];
        }
        for(int Status = 1; Status<(1<<n); Status++)
        {
            for(int i = 0; i<n; i++)
            {
                if(!(Status&(1<<i)))
                {
                    for(int j = 0; j<n; j++)
                    {
                        if((Status&(1<<j)))
                        {
                            dp[Status|(1<<i)][i] = max(dp[Status|(1<<i)][i],dp[Status][j] + a[i] + use[j][i]);
                        }
                    }
                }
            }
        }
        ll _max = 0;
        for(int Status = 0; Status<(1<<n); Status++)
        {
            int cnt = 0;
            for(int i = 0; i<n; i++)
            {
                if(Status&(1<<i))
                {
                    cnt++;
                }
            }
            if(cnt==m)
            {
                for(int i = 0; i<n; i++)
                {
                    _max = max(_max,dp[Status][i]);
                }
            }
        }
        printf("%lld\n",_max);
    }
    return 0;
}

0 0
原创粉丝点击