Atcoder beginner contest 175D

题目链接:https://atcoder.jp/contests/abc175/tasks/abc175_d
题目大意:从每个框开始,框上有索引,就得到改框的价值C,框可以移动k次,问从每个框都出发,中途能得到的最大价值。
题解:我们一眼望去就能想到的就是暴力,很明显的就是会t掉,我们注意到n远远小于k,且索引是1到n的排序,很明显一定能得到循环节,且循环节的大小一定小于等于n。
注意点:在计算过程中有一种特殊情况我们需要注意:
循环n次,可能比循环n-1次要差。
然后我们模拟就能愉快的ac了,细节看代码

#include 

using namespace std;
#define ll long long

const int N=1e6+100;

ll p[N],c[N];

ll vis[6000],g[6000];
ll n,k,step;
void A(int s)
{
     while(1){
        if(vis[s]) return ;
        step++;
        g[step]=g[step-1]+c[p[s]];
        vis[s]=1;
        s=p[s];
     }
}
void solve()
{
   cin>>n>>k;
   for(int i=1;i<=n;i++)
        cin>>p[i];
   for(int i=1;i<=n;i++)
       cin>>c[i];
   ll ans=-1e18;
   for(int i=1;i<=n;i++){
       ll kk=k;
       memset(vis,0,sizeof vis);
       for(int i=1;i<=n;i++) g[i]=-1e18;
       step=0;
       A(i);
       ll ma=g[step];
       for(int i=2;i<=step;i++){
          g[i]=max(g[i],g[i-1]);
       }
       ll ty=kk/step;

       if(ty>=1){
          ans=max(max(ans,g[step]),max(g[kk%step]+ty*ma,g[step]+(ty-1)*ma));
       }
       else {
        ans=max(ans,g[kk%step]);
       }
   }
    cout<<ans<<endl;
}
int main()
{
    ios::sync_with_stdio(0),cin.tie(0);
    solve();
    return 0;
}

请大佬们多多指教。

你可能感兴趣的:(算法)