[codeforces] Gym

来源:互联网 发布:ps软件中文免费下载 编辑:程序博客网 时间:2024/06/06 03:17

[codeforces] Gym - 100814E Everything Has Changed (DP)


题目链接:
Everything Has Changed


题目大意:
给你一个nm的矩阵, 让你从左上角走到右下角 只能往下或者往右选择一些数字相乘, 使得最后的乘积转换为6进制之后0的个数尽可能多。


数据范围:
2n,m100


解题思路:
要想一个数转换为六进制0尽可能多, 那么我们需要尽可能让一个数里2, 3的个数尽可能多。 所以我们可以先处理出每个数包含多少个2, 多少个3,之后再去DP处理, 我用dp[i][j][k] 表示ij列选k个3最多选几个2

#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#include <vector>#include <queue>#include <set>#include <map>#include <string>#include <cmath>#include <cstdlib>#include <ctime>using namespace std;typedef long long LL;const int MaxN = 100;struct NODE{    int c2, c3;}a[MaxN + 5][MaxN + 5];int dp[MaxN +5][MaxN + 5][MaxN * 20 + 5];int n, m, T;void solve(){    for(int i = 1; i <= n; i++)        for(int j = 1; j <= m; j++)            for(int k = a[i][j].c3; k <= 2000; k++){                if(dp[i - 1][j][k - a[i][j].c3] != -1)                    dp[i][j][k] = max(dp[i][j][k], dp[i - 1][j][k - a[i][j].c3] + a[i][j].c2);                if(dp[i][j - 1][k - a[i][j].c3] != -1)                    dp[i][j][k] = max(dp[i][j][k], dp[i][j - 1][k - a[i][j].c3] + a[i][j].c2);            }}int main(){    scanf("%d", &T);    while(T--){        scanf("%d %d", &n, &m);        for(int i = 1; i <= n; i++){            for(int j = 1; j <= m; j++){                int x;                scanf("%d", &x);                a[i][j].c2 = a[i][j].c3 = 0;                while(x % 2 == 0) a[i][j].c2++, x /= 2;                while(x % 3 == 0) a[i][j].c3++, x /= 3;            }        }        memset(dp, -1, sizeof(dp));        for(int i = 1; i <= n; i++) dp[i][0][0] = 0;        for(int j = 1; j <= m; j++) dp[0][j][0] = 0;        solve();        int ans = 0;        for(int k = 0; k <= 2000; k++) ans = max(ans, min(k, dp[n][m][k]));        printf("%d\n", ans);    }    return 0;}

标签(空格分隔): DP codeforces

原创粉丝点击