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。大家可以尝试换不同的方法写。

浙公网安备 33010602011771号