最大余数

24 篇文章 0 订阅
19 篇文章 0 订阅

题目描述

菜鸟是个奇怪的人,他整天喜欢琢磨一些东西...
某天,他在想:如果一个数k加上n次a而且乘上m次b,然后再对p取余,之后这个数最大会变成多少呢??
因为今天菜鸟在忙于期末考试,所以现在请你来帮助解决一下这个问题(对这个数每次你可以选择加a或者乘b, 但是你总的必须要用n次加法和m次乘法)。

输入

多组测试数据,第一行有一个整数t(1<=t<=20)代表case数量,对于每个case,有六个整数k,n,m,a,b,p分别代表这个数,n次加法,m次乘法,每次加上a,每次乘上b,最后对p取余(1<=k,n,m,a,b,p<=100)。

输出

每个case形如"Case #K: M",K代表case数,从1开始,M代表对k这个数在进行上面操作后对p取余的最大数.

样例输入

3
100 100 100 100 100 100
1 2 3 4 5 6
54 46 78 58 99 64

样例输出

Case #1: 0
Case #2: 5
Case #3: 62

 

开一个三维数组dp模拟状态,i,j表示+了多少次a,*了多少次b,结果为p成不成立,最后找最大的就可以

三种方法,第一种暴力明显超时233;

//第一种最简单的
# if 0
# include <iostream>
# include <cstdio>
# include <algorithm>
# include <cstring>

using namespace std;

const int maxn = 1e2 + 10;
bool dp[maxn][maxn][maxn];
int k, n, m, a, b, p;
int maxx = 0;
void dfs(int s_a, int s_b, int value)
{
    if(s_a > n)
    {
        return ;
    }
    if(s_b > m)
        return ;
    if(s_a == n && s_b == m && value > maxx)
    {
        maxx = value;
        return ;
    }
 //   cout << s_a << " " << s_b << " " << value << endl;
    dfs(s_a + 1, s_b, (value + a) % p);
    dfs(s_a , s_b + 1,(value * b) % p);
}

int main(int argc,char *argv[])
{
    int t;
    while(cin >> t)
    {
       for(int l = 1; l <= t; l++)
       {
           maxx = 0;
           memset(dp, false, sizeof(dp));
           cin >> k >> n >> m >> a >> b >> p;
           dp[0][0][k %p] = true;
           maxx = k % p;
           dfs(0, 0, k % p);

           cout <<"Case #"<< l<<": " << maxx<<endl;
       }
    }

}
#endif





# if 0
# include <iostream>
# include <cstdio>
# include <algorithm>
# include <cstring>

using namespace std;

const int maxn = 1e2 + 10;
bool dp[maxn][maxn][maxn];
int k, n, m, a, b, p;
int maxx = 0;
void dfs(int s_a, int s_b, int value)
{

    if(dp[s_a][s_b][value] || s_a > n || s_b > m)
    {
        return ;
    }
    dp[s_a][s_b][value] = true;
    if(s_a == n && s_b == m )
    {
        dp[s_a][s_b][value] = true;
        return ;
    }
    dfs(s_a + 1, s_b, (value + a) % p);
    dfs(s_a , s_b + 1,(value * b) % p);
}



int main(int argc,char *argv[])
{
    int t;
    while(cin >> t)
    {
       for(int l = 1; l <= t; l++)
       {
           maxx = 0;
           memset(dp, false, sizeof(dp));
           cin >> k >> n >> m >> a >> b >> p;
        //   dp[0][0][k %p] = true;
           dfs(0, 0, k % p);
          # if 01
           for(int i = p - 1; i >= 0; i--)
           {
               if(dp[n][m][i])
               {
                   maxx = i;
                   break;
               }
           }
           #endif

           cout <<"Case #"<< l<<": " << maxx<<endl;
       }
    }

}
#endif

//第三种
# if 1
# include <iostream>
# include <cstdio>
# include <algorithm>
# include <cstring>

using namespace std;

const int maxn = 1e2 + 10;
bool dp[maxn][maxn][maxn];
int k, n, m, a, b, p;
int maxx = 0;
int main(int argc, char *argv[])
{
    int t;
    while(cin >> t)
    {
       for(int l = 1; l <= t; l++)
       {
           maxx = 0;
           memset(dp, false, sizeof(dp));
           cin >> k >> n >> m >> a >> b >> p;
           dp[0][0][k % p] = true;
           for(int i = 0; i <= n; i++)
           {
               for(int j = 0; j <= m; j++)
               {
                   for(int g = 0; g < p; g++)
                   {
                       if(!dp[i][j][g])
                       {
                           continue ;
                       }
                       if(i + 1 <= n)
                            dp[i + 1][j][(g + a) % p] = true;
                       if(j + 1 <= m)
                            dp[i][j + 1][(g * b) % p] = true;
                     //   cout << i << " " << j << " " << (g + a) % p << " " <<(g * b) % p << endl;
                   }
               }
           }

           for(int i = p - 1; i >= 0; i--)
           {
               if(dp[n][m][i])
               {
                   maxx = i;
                   break;
               }
           }
           cout <<"Case #"<< l<<": " << maxx<<endl;
       }
    }
    return 0;
}


#endif

 

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值