• 2019 Sichuan Province Programming Contest J. Jump on Axis


    题目链接:https://codeforces.com/gym/102821/problem/J

    题意:给你一个坐标k,每次从0开始走

    每次有三个选择:选择1走一步,选择2走两步,选择3走三步

    每次选第i个选择的时候,如果他没有被选过,那么就走i步

    如果他被选过了的话就走上一次选择这个选择走过的步数+3步

    问:到k的最小步数和到k有多少种方法

    思路:我们把每次选择打表

     然后我们可以用一个二维数组v【i】【j】来预处理存选项i一共选了j次所走的路程

    设选项1走了i次,选项2走了j次,选项3走了k次

    我们只用列举一下i和j的路程,然后算出k

    如果满足条件更新步数ans=min(ans,i+j+k)

    然后对于每个满足的i j k,选择的方案是C(i+j+k,i)*C(j+k,j)

    (在i+j+k个位置里选i个位置走选项1,在剩下的j+k个位置走选项2)

    然后我们化简一下就是:

    因为需要取模,然后我们就要用逆元求一下阶乘的倒数r【i!】数组,还需要求一下阶乘f【i】数组 

    由打表可以知道i,j,k不超过2600个,

    而且最后是i+j+k,那么我们就开3*3000个数组

    具体代码如下:

    1. #include<bits/stdc++.h>
    2. using namespace std;
    3. #define int long long
    4. typedef long long ll;
    5. int n,ans,con;
    6. const int N=3*3000,mod=1e9+7;
    7. int f[N],r[N];
    8. vector<int> v[5];
    9. int ksm(int a,int b,int p){
    10. int res=1%p;
    11. while(b){
    12. if(b&1)res=res*a%p;
    13. a=a*a%p;
    14. b>>=1;
    15. }
    16. return res;
    17. }
    18. void init(){
    19. for(int i=1;i<=3;i++){//预处理选项i选了j次走的路程
    20. v[i].push_back(0);//当选0次的时候走了0
    21. for(int j=1;;j++){
    22. int op=v[i][j-1]+(j-1)*3+i;
    23. if(op>1e7)break;//当大于1e7的时候剪枝
    24. v[i].push_back(op);
    25. }
    26. v[i].push_back(1e9); //最后加上个大整数是方便lower_bound查找
    27. }
    28. f[0]=r[0]=1;
    29. for(int i=1;i<N;i++){//处理阶乘
    30. f[i]=f[i-1]*i%mod;
    31. }
    32. for(int i=1;i<N;i++){//处理阶乘的逆元
    33. r[i]=ksm(f[i],mod-2,mod);
    34. }
    35. }
    36. signed main(){
    37. init();
    38. int t;
    39. scanf("%lld",&t);
    40. for(int p=1;p<=t;p++){
    41. ans=1e9;
    42. cin>>n;
    43. con=0;
    44. for(int i=0;v[1][i]<=n;i++){//列举选项1
    45. for(int j=0;v[1][i]+v[2][j]<=n;j++){//列举选项2
    46. int x=n-v[1][i]-v[2][j];//算选项3
    47. int k=lower_bound(v[3].begin() ,v[3].end() ,x )-v[3].begin() ;
    48. if(v[3][k]==x){//如果满足
    49. ans=min(ans,i+j+k);
    50. con=(con+f[i+j+k]*r[i]%mod*r[j]%mod*r[k]%mod)%mod;
    51. }
    52. }
    53. }
    54. printf("Case %lld: %lld %lld\n",p,ans,con);
    55. }
    56. return 0;
    57. }

  • 相关阅读:
    Go在安装Gin时出现Failed to connect 报错问题的解决方案(已解决)
    现代物流有哪些特点?
    【目标检测】41、CSPNet | 一种加强 CNN 模型学习能力的主干网络
    【数据挖掘】数据统计性描述与相似度
    javascript 正则表达式匹配替换
    java如何防止表单重复提交:使用Token机制防止表单重复提交
    SpringBoot使用Redisson 实现分布式锁
    1688拍立淘API接口分享
    基于Java纯净水商城配送系统设计与实现 开题报告
    基于PHP+MySQL学院信息发布系统的设计与实现
  • 原文地址:https://blog.csdn.net/qq_61903556/article/details/127656041