【动态规划】【倒序】codeforces102056I Misunderstood … Missing

I. Misunderstood … Missing
time limit per test1.0 s
memory limit per test256 MB
inputstandard input
outputstandard 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 A and an increment D of it, which are both 0 initially. There are n rounds in total. For i=1,2,…,n, at the beginning of i-th round Rikka’s aggressivity A increases by the increment D, and then she can do one of the following:

Attack and cause a damage of (A+ai).
Use the Omnipotent Garland from LCR to increase the increment D by bi.
Use her Schwarz Sechs Prototype Mark II to increase the aggressivity A by ci.
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), the number of test cases. Then T test cases follow.

The input format of each test case is as follows:

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

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

It is guaranteed that the sum of n in all test cases is at most 100.

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


 今天和队友们一起模拟了EC-final的比赛。其间Hardict解了一道我根本没思路的dp题,后来仔细领会了一下,感觉确实很精彩,于是记录一下(感谢这么可靠的队友!)
 首先题目肯定是dp了。一般人的思路肯定是顺着来做,包括我。可以发现顺着做的话,无论如何都要记录当前的攻击力A和当前的增量D,这两个数字本身就是大,不可能作为dp状态的维度。队友提醒我倒着做的时候还没反应过来QwQ。
 倒着dp有什么好处呢?我们知道,我们之所以顺着来的时候要记录A和D,是因为不记录必然有后效性。但有后效性不意味着有“前效性”,首先可以发现,倒着每做一次选择,它对答案产生的贡献更好确定。具体怎么确定呢,我们知道,只要记录考虑到第i步时,此后攻击了j步,那么第三个选择的贡献可以确定,是c[i]*j,而第二个选择,还需要记录这些攻击的下标之和(这个设计也很精彩!)
 具体的转移方程看代码,另外附他人详细的题解:https://www.cnblogs.com/Cwolf9/p/10138441.html
 状态太多的话可以考虑滚动数组。

#include<cstdio>
#include<algorithm>
using namespace std;
using LL=long long;

LL dp[2][105][5505],a[105],b[105],c[105],ans,tmp,o;
int T,n;

inline bool check(int i, int j, int k)
{
	return i<=n&&j>0&&(i*2+j-1)*j/2<=k&&(n*2-j+1)*j/2>=k;  //检查状态合法性
}

int main()
{
	scanf("%d",&T);
	while(T--)
	{
		ans=0;
		scanf("%d",&n);
		for(int i=1;i<=n;i++)
			scanf("%lld%lld%lld",&a[i],&b[i],&c[i]);
		for(int i=n;i>0;i--)
		{
			for(int j=1;j<=n-i+1;j++)
				for(int k=(i*2+j-1)*j/2;k<=(n*2-j+1)*j/2;k++)
				{
					tmp=check(i+1,j,k)?dp[o^1][j][k]+max(c[i]*j,(k-i*j)*b[i]):0;
					dp[o][j][k]=max((check(i+1,j-1,k-i)?dp[o^1][j-1][k-i]:0)+a[i],tmp);
				}
			o^=1;
		}
		for(int j=1;j<=n;j++)
			for(int k=(j+1)*j/2;k<=(n*2-j+1)*j/2;k++)
				ans=max(dp[o^1][j][k],ans);
		printf("%lld\n",ans);
	}
	return 0;
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值