【动态规划】【集合】False Mirrors

来源:互联网 发布:农业税 知乎 编辑:程序博客网 时间:2024/06/15 18:52

1152. False Mirrors

Time Limit: 2.0 second
Memory Limit: 16 MB

Background

We wandered in the labyrinth for twenty minutes before finally entering the large hall. The walls were covered by mirrors here as well. Under the ceiling hung small balconies where monsters stood. I had never seen this kind before. They had big bulging eyes, long hands firmly holding riffles and scaly, human-like bodies. The guards fired at me from the balconies, I shot back using my BFG-9000. The shot shattered three mirrors filling the room with silvery smoke. Bullets drummed against my body-armor knocking me down to the floor. Falling down I let go a shot, and got up as fast as I fell down by rotating on my back, like I did in my youth while break dancing, all this while shooting three more times. Three mirrors, three mirrors, three mirrors…

Sergey Lukjanenko, “The Labyrinth of Reflections”

Problem

BFG-9000 destroys three adjacent balconies per one shoot. (N-th balcony is adjacent to the first one). After the shoot the survival monsters inflict damage to Leonid (main hero of the novel) — one unit per monster. Further follows new shoot and so on until all monsters will perish. It is required to define the minimum amount of damage, which can take Leonid.

Input

The first line contains integer N, аmount of balconies, on which monsters have taken a circular defense. 3 ≤N ≤ 20. The second line contains N integers, amount of monsters on each balcony (not less than 1 and no more than 100 on each).

Output

Output minimum amount of damage.

Sample

input

output

73 4 2 2 1 4 1

9

 

这道集合动规应该算是比较简单的,但是题目理解错了,导致做了两天。

最重要的是,每一次攻击,攻击的都是绝对相邻的,即如果破坏了两个阳台之间的阳台,这两个阳台仍然不相邻。

用f来记录答案,用Sum来记录某一个状态对应的已经破坏的阳台代价之和。

 

#include <cstdio>#include <string>struct node{long id;long s;node* nxt;};const long hmod = 1000000;node sto[1000000];long sta[2][1000000];long f[2][1000000];long Sum[2][1000000];long sum = 0; node* head[1000000];long ths = 0;long pre = 1;long cnt[2];long num[30];long getint(){char tmp;long rs=0;bool sgn=1;do tmp=getchar();while (!isdigit(tmp)&&tmp-'-');if (tmp=='-'){tmp=getchar();sgn=0;}do rs=(rs<<3)+(rs<<1)+tmp-'0';while (isdigit(tmp=getchar()));return sgn?rs:-rs;}long getid(long s){long h = s % hmod;node* u = head[h];while (u){if (u->s == s){return u->id;}u = u->nxt;}cnt[ths] ++;sto[cnt[ths]].id = cnt[ths];sto[cnt[ths]].s = s;f[ths][cnt[ths]] = 0;Sum[ths][cnt[ths]] = 0;sta[ths][cnt[ths]] = s;sto[cnt[ths]].nxt = head[h];head[h] = &sto[cnt[ths]];return cnt[ths];}void clear(){cnt[ths] = 0;memset(head,0,sizeof head);}void updata(long &a,long &b,long c,long d,long e){if (a > c+sum-d-e || a == 0){a = c+sum-d-e;b = d + e;}}int main(){freopen("tfm.in","r",stdin);freopen("tfm.out","w",stdout);long n = getint();for (long i=0;i<n;i++)sum += num[i] = getint();f[ths][getid(0)] = 0;long ans = 0x7f7f7f7f;while (cnt[ths]){pre^=1;ths^=1;clear();for (long s=1;s<cnt[pre]+1;s++){long last = sta[pre][s];if (last == (1<<n)-1){ans = ans<f[pre][s]?ans:f[pre][s];continue;}for (long d1=0;d1<n;d1++){if (!(last & (1<<d1))) {long delta = num[d1];long ss = last | (1<<d1);if (!(last & (1<<((d1+1)%n)))){delta += num[(d1+1)%n];ss |= (1<<((d1+1)%n)); }if (!(last & (1<<((d1+2)%n)))){delta += num[(d1+2)%n];ss |= (1<<((d1+2)%n));}long id = getid(ss);updata(f[ths][id],Sum[ths][id],f[pre][s],Sum[pre][s],delta);}}}}printf("%ld",ans);return 0;}


 

原创粉丝点击