木子亚日乀  

C - Candies

链接:https://arc090.contest.atcoder.jp/tasks/arc090_a

题意:从左上角走到右下角,只能向右和向下走,问能最多能拿多少糖果。

思路:dp[i][j]=max(dp[i-1][j],dp[i][j-1])+dp[i][j];

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int dp[5][105];
int n;
int main()
{
    cin>>n;
    for(int i=1;i<=2;i++)
        for(int j=1;j<=n;j++)
        cin>>dp[i][j];
    for(int i=1;i<=2;i++)
        for(int j=1;j<=n;j++)
        dp[i][j]=max(dp[i-1][j],dp[i][j-1])+dp[i][j];
    cout<<dp[2][n]<<endl;
    return 0;
}

D - People on a Line

链接:https://arc090.contest.atcoder.jp/tasks/arc090_b

题意:坐标上有N个点,给出M条边。没条边给出L R D,意思为L在R的左边距离R的距离为D。

思路:带权的并查集。对并查集的认识再次上升一个高度,之前都是处理结点是不是在同一个集合,这次还要处理结点之间的距离,第一次遇到这种带权值的题目,把儿子到父亲的距离想的太简单了(其实是太菜)Orz,找了两个小时的bug。

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define maxn 100005
int pre[maxn];
int dis[maxn];
int n,m,l,r,d,fl,fr;
void init()
{
    for(int i=1;i<=n;i++)
        pre[i]=i,dis[i]=0;
}
int Find(int x)
{
    if(pre[x]==x)
        return x;
    int fa=pre[x];
    pre[x]=Find(pre[x]);
    dis[x]+=dis[fa];
    return pre[x];
}
int same(int l,int r)
{
    fl=Find(l);
    fr=Find(r);
    if(fl==fr)
        return 1;
    else
        return 0;
}
void unite()
{
    pre[fr]=fl;
    dis[fr]=dis[l]+d-dis[r];
}
int main()
{
    cin>>n>>m;
    init();
    int flag=0;
    while(m--)
    {
        cin>>l>>r>>d;
        if(flag)
            continue;
        if(!same(l,r))
        {
            unite();
        }
        else
        {
            if(dis[r]-dis[l]!=d)
                flag=1;
        }
    }
    if(flag)
        cout<<"No"<<endl;
    else
        cout<<"Yes"<<endl;
    return 0;
}

 

这个题目我看在AT上看了其他人的代码,有用最短路写的,也有用搜索写的,orz。大家可以尝试换不同的方法写。

posted on 2018-01-29 17:20  木子亚日乀  阅读(259)  评论(0)    收藏  举报