• Educational Codeforces Round 122 (Rated for Div. 2) D. Make Them Equal


    Problem - D - Codeforces

    题意:

    给定三个数组a,b,c,其中a数组一开始为1,b和c数组是给定的。

    对于每次操作,都可以选定一个i,任选一个x,使a[i]=a[i]+a[i]/x

    操作最多执行k次

    经过若干次操作后,若a[i]==b[i],则可以获得c[i]的价值

    问可以获得的最大价值是多少

    思路:

    有限制的价值问题,考虑做01背包

    因此我们要去确定v[i]和w[i]的值

    很显然在这道题中,w[i]=c[i]

    因此我们去看v[i]的值,即a[i]从1变到b[i]的最少步数是多少

    一开始想的是贪心,先一直取x=1,这样的话就相当于是二进制往上跳,但是这样的话,等我们跳到快超过b[i]的最后一步时,是否存在x使得a[i]+a[i]/x==b[i]这件事是难以判断的,因此这样的思路可以排除

    因为要求最少步数,所以应该要想到求BFS最短路,而且这道题的数据范围很小,因此求最短路的思路更为合理

    我们去预处理最短路数组dis,表示从1到b[i]的最短路的长度,这样v[i]的值就相当于是dis[b[i]]的值

    求出v[i]之后去跑一边01背包即可

    需要注意我们从1经过操作后变成b[i]的最少步数最多也就12步(二进制),所以总操作步数取min(12*n,k)即可

    这道题思路较为自然,但是最短路那一步还是没有想到

    Code:

    1. #include
    2. using namespace std;
    3. #define int long long
    4. const int mxn=1e3+10,mxe=2e5+10,mnf=1e18;
    5. queue<int> q;
    6. int n,k;
    7. int b[mxn],c[mxn],dp[mxn*12],v[mxn],dis[mxn];
    8. void solve(){
    9. memset(dp,0,sizeof(dp));
    10. cin>>n>>k;
    11. k=min(k,12ll*n);
    12. for(int i=1;i<=n;i++) cin>>b[i];
    13. for(int i=1;i<=n;i++) cin>>c[i];
    14. for(int i=1;i<=n;i++) v[i]=dis[b[i]];
    15. for(int i=1;i<=n;i++){
    16. for(int j=k;j>=v[i];j--) dp[j]=max(dp[j],dp[j-v[i]]+c[i]);
    17. }
    18. cout<<*max_element(dp,dp+1+k)<<'\n';
    19. }
    20. void init(){
    21. memset(dis,0x3f,sizeof(dis));
    22. dis[1]=0;
    23. q.push(1);
    24. while(!q.empty()){
    25. int u=q.front();
    26. q.pop();
    27. for(int x=1;x<=u;x++){
    28. int v=u+u/x;
    29. if(v<=1e3&&dis[v]>dis[u]+1){
    30. dis[v]=dis[u]+1;
    31. q.push(v);
    32. }
    33. }
    34. }
    35. }
    36. signed main(){
    37. ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    38. int T=1;
    39. cin>>T;
    40. init();
    41. while(T--)solve();
    42. return 0;
    43. }

    总结:

    1.如果我们要去跑01背包的话,先去确定它v[i]和w[i]的值

    2.求最少步数应当想到最短路

  • 相关阅读:
    Nignx安装&负载均衡&动静分离以及Linux前端项目部署&将域名映射到特定IP地址
    设计模式之装饰着模式(七)
    解决http请求下无法开启麦克风问题
    L13.linux命令每日一练 -- 第二章 文件和目录操作命令 -- lsattr和file命令
    Flink 简单 入门大纲
    基于微信小程序的车位预定系统设计与实现(源码+lw+部署文档+讲解等)
    Vue3从零开始——掌握setup、ref和reactive函数的奥秘
    c++编写天天酷跑游戏
    Mybatis
    函数式编程-Stream流(三更草堂)
  • 原文地址:https://blog.csdn.net/weixin_62528401/article/details/128165959