atcoder beginner const 265补题

本文探讨了两个编程问题:一是通过二分查找和dp实现坐标变换路径计数,避免故障区域;二是利用曼哈顿距离和动态规划解决前缀和问题,寻找符合条件的r值。通过这两个算法,解决在给定约束下路径选择和和值计算问题。

D

思路:创建set集合,从出现的已有前缀和中找到是否有当前前缀和加p,q,r和的存在;

2种方法:1、set.find;存在则不等于空,即不等于s.end();2、二分,查找,鉴于数据过大;选择二分;

#include<bits/stdc++.h>
using namespace std;
const int N=2e5+10;
#define ll long long
ll a[N];
ll n,p,q,r,ans=0;
set<ll>s({0});
int main()
{
    cin>>n>>p>>q>>r;
    for(int i=0;i<n;i++)
    {
        cin>>a[i];
        ans+=a[i];
        s.insert(ans);
    }
    for(auto x:s)
    {
        if(s.find(x+p)!=s.end()&&s.find(x+p+q)!=s.end()&&s.find(x+p+q+r)!=s.end())
        {
            cout<<"Yes"<<endl;
            return 0;
        }
    }
    cout<<"No"<<endl;
    return 0;
}

E; dp

 

题意:从(x,y)坐标变换,至 x+a,y+b or ,x+c,y+d or,x+e,y+f;

不能移动到故障坐标;求可以总共走的路径在n次内移动;

无终点限制、仅要求步数;不能踩的点;

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N=1e5,mod=998244353;
int n,m;
ll a,b,c,d,e,f,sum=0;
typedef pair<ll,ll>PII;
PII q[N];//存故障坐标 
#define x first
#define y second
ll dp[303][303][303];//存每一次移动步数 
bool cmp(PII t1,PII t2)
{
    if(t1.x==t2.x)
    return t1.y<t2.y;
    return t1.x<t2.x;
}
int main()
{
    cin>>n>>m;
    cin>>a>>b>>c>>d>>e>>f;
    for(int i=0;i<m;i++)
    cin>>q[i].x>>q[i].y;
    sort(q,q+m,cmp);
    dp[0][0][0]=1;
    for(int i=0;i<=n;i++)//一共进行n次,某一次变化可选可不选,所以有0; 
    {
        for(int j=0;j<=n-i;j++)
        {
            for(int k=0;k<=n-i-j;k++)//x坐标增加的是a、c、e的倍数; 
            {
                ll xx=i*a+j*c+k*e;
                ll yy=i*b+j*d+k*f;
                ll l=0,r=m-1,ans=0;
                while(l<=r)//二分从故障坐标种找是否有重合和已选坐标; 
                {
                    ll mid=l+r>>1;
                    if(q[mid].x<xx||(q[mid].x==xx&&q[mid].y<yy))
                    l=mid+1;
                    else
                    r=mid-1;
                }
                if(q[l].x==xx&&q[l].y==yy&&l!=m)continue;//l不能越边界; 
                //符合条件的则进行方案数增加;每一次都可从前一个来; 
                if(i)dp[i][j][k]+=dp[i-1][j][k];
                if(j)dp[i][j][k]+=dp[i][j-1][k];
                if(k)dp[i][j][k]+=dp[i][j][k-1];
                dp[i][j][k]%=mod;
            }
        }
    }
    for(int i=0;i<=n;i++)
    {
        for(int j=0;j<=n-i;j++)
        {
            int k=n-i-j;
            sum=(sum+dp[i][j][k])%mod;
        }
    }//最后计算的是每一步的总和; 
    cout<<sum;
    return 0;
}

F:F - Manhattan Cafe

 

题意:给定p、q找到符合条件的r的个数;条件:在p[i]的前i个曼哈顿和(p到r)<=D,且q[i]的前i个曼哈顿和(p到r)<=D;

解题:

曼哈顿距离+dp

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值