2018-2019 ACM-ICPC, Asia East Continent Finals I Misunderstood … Missing(level-2)(将未知量作为dp数组的某一维)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_37025443/article/details/86406139

I. Misunderstood … Missing

time limit per test

1.0 s

memory limit per test

256 MB

input

standard input

output

standard output

Warm sunshine, cool wind and a fine day, while the girl watching is pursuing in chaos. Rikka reached out her hand and got the garland on her head, finding LCR with the immortal smile. The dream ended up waking, but the doubts will never disappear. In the end, without knowing about LCR, Rikka was invited to Shuyuan Men, a street of Chinese traditional arts in Xi'an.

"Is it enough to use the stored wires?"

"No problem... Those leaders are only concerned about expanding EC Final for the school's and their 'achievements'. All chores are ours. It is fine to simply connect those wiring boards in the series for each row."

Their conversation engaged Rikka. Feeling strange, she decided to follow them. But before all, she needs to beat the devil in her heart.

Rikka has an aggressivity AA and an increment DD of it, which are both 00 initially. There are nn rounds in total. For i=1,2,…,ni=1,2,…,n , at the beginning of ii -th round Rikka's aggressivity AA increases by the increment DD , and then she can do one of the following:

  1. Attack and cause a damage of (A+ai)(A+ai) .
  2. Use the Omnipotent Garland from LCR to increase the increment DD by bibi .
  3. Use her Schwarz Sechs Prototype Mark II to increase the aggressivity AA by cici .

Rikka wonders the maximal possible damage she could cause in total. Could you help her?

Input

The first line contains a single integer T (1≤T≤10)T (1≤T≤10) , the number of test cases. Then TT test cases follow.

The input format of each test case is as follows:

The first line contains a single integer n (1≤n≤100)n (1≤n≤100) , the number of rounds.

The following nn lines contain {ai},{bi},{ci}{ai},{bi},{ci} for i=1,2,…,ni=1,2,…,n . The ii -th line among them contains three integers ai,bi,ci (1≤ai,bi,ci≤109)ai,bi,ci (1≤ai,bi,ci≤109) separated by spaces in order.

It is guaranteed that the sum of nn in all test cases is at most 100100 .

Output

Output TT lines; each line contains one integer, the answer to that test case.

Example

Input

Copy

3
2
3 1 2
3 1 2
3
3 1 2
3 1 2
3 1 2
5
3 1 2
3 1 2
3 1 2
3 1 2
3 1 2

Output

Copy

6
10
24

题意:

你现在有攻击力A=0和增长值D=0

每一回合,你的攻击力会增加,A=A+D

然后进行选择,1.发出攻击,伤害为ai+A

2.增加D,D=D+bi

3.增加A,A=A+ci

问你经过n轮之后,最大的伤害值是多少

解析:

这道题想了接近一天,但一点都没有思路。

因为这道题对于每一种选择,依据是不同的,选择ai是依据攻击力A(即依据在他之前的回合的选择)

ci,bi是依据下面选择1的回合数(即在他之后的选择),只有这样,才能比较三者的贡献,然后取最大值

我的思路是这样的,但是这个思路是按照类似贪心的思路取选择的,即每遍历到一轮,就想选定他的选择

但是按照动态规划的思路,我们不需要去选择,只需要去记录就可以了,即选择每一轮的所能达到的贡献。

我们从自底向上推,那么对于ci,bi依赖的是下面选择1的回合数及其位置,这些是未知的。

在动态规划中未知的量,我们可以把他作为dp数组中的某一维,那么在求解的过程中我们就可以把他当作已知量

来暴力枚举每一种可能值。(如果时间允许的话)

因为这些未知量都是未知的条件,且都会对最终的答案产生影响。

所以在本题中,我们需要知道的是对于第i轮,第i+1...n轮中选择1的个数,以及他们的标号和。

因为对于bi,假定下面第p轮是选择1的,那么bi就会对第p轮造成贡献(p-i)*bi,那么如果下面有第p1,p2,p3,...pk轮选择1

,那么选择bi的贡献就是(p1+p2+p3+...+pk-k*i)*bi。

那么我们的dp数组就开成dp[101][101][5100]->dp[i][j][k]:表示在i+1...n轮中,有j轮选择1且选择1的编号和是k的最大的贡献和

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
 
typedef long long ll;
ll dp[2][101][5100];
int a[101],b[101],c[101];
 
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int n;
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            scanf("%d%d%d",&a[i],&b[i],&c[i]);
        }
        memset(dp[0],0,sizeof(dp[0]));
        dp[0][1][n]=a[n];
        int now=0;
        for(int i=n-1;i>=1;i--)
        {
            int nex=now^1;
            memset(dp[nex],0,sizeof(dp[nex]));
            for(int j=1;j<=n-i;j++)
            {
                int vv=(n+n-j+1)*j/2;
                for(int k=1;k<=vv;k++)
                {
                    if(!dp[now][j][k]) continue;
                    dp[nex][j+1][k+i]=max(dp[now][j][k]+a[i],dp[nex][j+1][k+i]);
                    dp[nex][j][k]=max(dp[nex][j][k],dp[now][j][k]+1ll*j*c[i]);
                    dp[nex][j][k]=max(dp[nex][j][k],dp[now][j][k]+1ll*(k-j*i)*b[i]);
                }
            }
            now=nex;
        }
        ll ans=0;
        for(int j=1;j<=n;j++)
        {
            int vv=(n+n-j+1)*j/2;
            for(int k=1;k<=vv;k++)
            {
                ans=max(ans,dp[now][j][k]);
            }
        }
        printf("%lld\n",ans);
    }
}

猜你喜欢

转载自blog.csdn.net/qq_37025443/article/details/86406139