P6622(算内存)(之后来做了,实在不行了)
下次看到每一道题都要认真读题啊啊啊啊啊啊啊啊啊啊啊啊啊啊
设\(dp_{S,i}\)为走出集合S的时间最小值,然后枚举集合转移。因为控制塔的位置是不变的所以
i->j的贡献如下:
\(j-i (j>i) \\ k(i+j) (j<i)\)
看这个时间应该是\(O(m2^{m})\)的,所以我们要预处理集合S走到\(S+i\)的贡献,一个想法是递推转移,好像只能这样了。我们可以知道集合S前的都在S前,用的是第一个公式,而没有填的用的是第二个公式。那么贡献就应该是
\(\sum tot[j->i]*(id_{i}-id_{j})+\sum tot[i->j]*k*(id_{i}+id_{j})\)
\(\sum tot[j->i]*id_{i}-\sum tot[j->i]*id_{j}+\sum tot[i->j]*k*id_{i}+\sum tot[i->j]*k*id_{j}\)
\(\sum tot[j->i]*id_{i}+\sum tot[i->j]*k*id_{i}-\sum tot[j->i]*id_{j}+\sum tot[i->j]*k*id_{j}\)
\(\sum id_{i}*(tot[j->i]+tot[i->j]*k)+\sum id_{j}*(tot[i->j]*k-tot[j->i])\)
然后把这个搞出来就是O(m{2}2)的做法,考虑优化。我们从ans[i-lowbit(i)][j]推到ans[i][j]需要变化贡献。原来是有j对i的贡献的,因为原来i被排在j之后了,我们需要减掉。这部分是(tot[j][i]-ktot[i][j]),然后加上i对j的贡献,是(ktot[i][j]+tot[j][i])
\(dp_{S}=min(dp{S-i}+g(S-i,i))\)。但是23*2^23是开不下的,需要考虑优化。最简单的一个优化(中午想到的)就是如果我们\(dp_{S,i}\)一定有i,那么就可不记录i,这样的常数也不会太大,由于状压的超小常数,和3s的时间加持这应该是可以过的。
复习下初赛:
1B(byte,字节)= 8 bit(比特,即为位);
1KB(Kilobyte,千字节)=1024B= 2^10 B;
一个bit是0/1,我们常常听到32位操作系统,64位,这就是有多少比特,所以1个int是4B,注意一个1个bool是1B
所以1MB=2^10 KB=2^20 B。所以1MB大概是218个int,那么这题我开了23*222个int那么就是23*2^4MB=368MB,可过。小朋友再也不用担心算内存了!