Quantum
Description At the Institution for Bits and Bytes at University of Ramville, Prof. Jeremy Longword and his eight graduate students are investigating a brand new way of storing and manipulating data on magnetic disks for use in hard drives. The method is based on letting quasimagnetic quantum operations operate on the sectors on the disk, and is, of course, safer andmore reliable than any earlier invented storage method. The use of each quantum operation costs a certain amount of energy, and the more energy the storage unit consumes, the warmer it will get. Therefore, you and your research team, are assigned the task of writing a program that, given sets of possible quantum operations and their costs, can calculate the lowest possible total cost for transforming a set of data to the wanted result. On the disk, binary words of length 1 ≤ L ≤ 20 are treated. The quantum operations are defined by strings of the same length as the binary words, and are built from the four letters N (does nothing), F (inverts one bit), S (sets a bit to 1), and C (resets a bit to 0). Each letter in the string corresponds to an operation on the bit in the binary word at the same position. The binary words are transformed one by one and the total energy cost for the transformation is calculated as the sum of the costs for the performed quantum operations. Input The input starts with a single positive integer N ≤ 20 on a row, deciding the number of test cases that will follow. Then, for each of the test cases:
After this, nop rows follows, each of them containing the definition of a quantum operation followed by the energy cost 0 ≤ ci 1000 of carrying out the quantum operation. The definition and the cost are separated by a single space. Finally, there are nw rows, each containing two binary words separated by a single space. The first of these words should, when possible, be transformed to the second using the quantum operations. The binary words are expressed as sequences of 1’ s and 0’s. After these rows, the next test case follows, if there is any. Output Each test case should produce a row containing a list of the energy costs of transforming each of the binary words. The costs should be separated by a single space and presented in the same order as the corresponding input. When there is no successful way of transforming a binary word, “NP”, meaning not possible should be printed instead. Sample Input 2 4 3 3 NFFN 1 NFNF 2 NNFN 4 0010 0100 0001 0010 0100 1000 4 4 5 CFSF 4 NNSS 3 FFFF 5 FNFN 6 1111 0000 1001 0110 0101 1000 1000 0011 0000 1001 Sample Output 1 3 NP 5 4 8 9 9 Source |
思路:
记忆化广搜+状态压缩。可以用二进制进行状态压缩。这里需要注意的是当前状态出现过了,以后依然可能更新当前状态的cost。不能天真的以为对操作的cost进行排序并且用优先队列就不用更新状态了。
代码:
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<queue>
using namespace std;
struct opt
{
char str[25];
long long cost;
bool operator <(opt a)const
{
return cost>a.cost;
}
}op[35];
struct node
{
int now[25];
long long cost;
bool operator <(node a)const
{
return cost>a.cost;
}
}p;
int n,nop,nw;
int beg[25],goal[25];
int vis[2100000];
int hash(int now[])
{
int h=0;
for(int i=0;i<n;i++)
h=(h<<1)+now[i];
return h;
}
long long bfs()
{
priority_queue<node> q;
memset(vis,-1,sizeof vis);
int h;
h=hash(beg);
vis[h]=0;
memcpy(p.now,beg,n*sizeof(int));
p.cost=0;
q.push(p);
while(!q.empty())
{
node top=q.top(); q.pop();
if(memcmp(top.now,goal,n*sizeof(int))==0) return top.cost;
for(int i=0;i<nop;i++)
{
for(int j=0;j<n;j++)
{
if(op[i].str[j]=='N') p.now[j]=top.now[j];
else if(op[i].str[j]=='F') p.now[j]=!top.now[j];
else if(op[i].str[j]=='S') p.now[j]=1;
else if(op[i].str[j]=='C') p.now[j]=0;
}
h=hash(p.now);
p.cost=top.cost+op[i].cost;
if(vis[h]!=-1 && vis[h]<=p.cost) continue;
vis[h]=p.cost;
q.push(p);
}
}
return -1;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d%d%d",&n,&nop,&nw);
for(int i=0;i<nop;i++)
scanf("%s%lld",op[i].str,&op[i].cost);
for(int i=0;i<nw;i++)
{
for(int j=0;j<n;j++)
scanf("%1d",&beg[j]);
for(int j=0;j<n;j++)
scanf("%1d",&goal[j]);
long long f=bfs();
if(i) printf(" ");
if(f==-1) printf("NP");
else printf("%lld",f);
}
printf("\n");
}
return 0;
}