WOJ Your NP has been charged full(普通dp)

来源:互联网 发布:枣想核你在一起 淘宝 编辑:程序博客网 时间:2024/06/13 21:18

题目分析

现场赛看了这道题并没有写,是因为队友说的题意我理解多了,本来是一个buff三回合之后就没有了,但是我认为只要加上了一个buff那么久一直有这个buff,想dp方程的时候发现有后效性,然后就写不出来了。回来之后重新读题发现一个buff三回合之后消失,那么很明显我们就可以只需知道这回合,上回合以及上上回合选什么buff,然后就可以直接写状态转移方程了,时间复杂度O(n33)。这里我的dp[i][j][k]表示到底i个回合,这个回合选第j个buff,上个回合选第k个buff。

#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>using namespace std;const int maxn = 1e4+100;double a[maxn][4], dp[maxn][4][4];double solve(int id, int _a, int _b, int _c){    double tot[4];    tot[1] = tot[2] = tot[3] = 1.0;    tot[_a] += a[id][_a];    tot[_b] += a[id-1][_b];    tot[_c] += a[id-2][_c];    return tot[1]*tot[2]*tot[3];}int main(){    int n;    while(scanf("%d", &n) != EOF){        memset(a, 0, sizeof(a));        memset(dp, 0, sizeof(dp));        for(int i = 1; i <= n; i++)            for(int j = 1; j <= 3; j++)                scanf("%lf", &a[i][j]);        for(int i = 1; i <= 3; i++)            for(int j = 1; j <= 3; j++)                if(i == j)  dp[2][i][j] = (1.0+a[1][j])+(1.0+a[1][j]+a[2][i]);                else dp[2][i][j] = (1.0+a[1][j]) + (1.0+a[1][j])*(1.0+a[2][i]);        for(int i = 3; i <= n; i++){            for(int aa = 1; aa <= 3; aa++){                for(int bb = 1; bb <= 3; bb++){                    for(int cc = 1; cc <= 3; cc++){                        dp[i][aa][bb] = max(dp[i][aa][bb], dp[i-1][bb][cc] + solve(i, aa, bb, cc));                    }                }            }        }        double ans = 0;        for(int i = 1; i <= 3; i++)            for(int j = 1; j <= 3; j++)             ans = max(ans, dp[n][i][j]);        printf("%.6lf\n", ans);    }    return 0;}
0 0
原创粉丝点击