很自然的想法,f[n][41][41][41][41]. 表示到第i个点,4种卡片剩余个数,最大得分。
递推很简单,看下就懂。
不过时间复杂度是350*40*40*40*40会T。
这个时候就有2种优化:
第一种: 1977ms,1496kb
由于总卡片数固定,且最后都用完,我们可以省去一维卡片。
f[n][41][41][41],到达某个点,前三种卡片数量知道了,最后一种的个数也就知道了。
到达终点的状态一定是f[n][0][0][0].(第四种一定也是0,不然到不了终点)
由于终点状态确定,我们就没必要算出第四种卡片数量来限制了。直接算就行。(如果四种卡片数量任意,就要算第四种卡片数量,来进行约束,也就是一个if的事情)
然后就是,这样空间会MLE。86MB,题目只给了64MB.
所以还要再优化,我们采用滚动数组的思想。发现 每次i只对i+1,i+2,i+3,i+4有影响,即每次只用到5个。
我们用取模5来进行滚动即可。
注意每次清空无用的数组,这题比较特殊,后面的点一定大于前面的点,所以就没必要清空了
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int f[6][41][41][41];//爬行到i时,1,2,3卡片还剩j,k,l时,能得到