题目描述
菜鸟是个奇怪的人,他整天喜欢琢磨一些东西...
某天,他在想:如果一个数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