POJ - 2908 Quantum 最短路(dj)+记忆化搜索

题目链接

 

题意:有长L的要操作01串nw个,目标01串nw,长L的操作符串nop,第i个操作符串每次使用将花费ci。求每个01串变成对应的目标串所需要的最小花费,若无解则输出NP。

 

思路:把每个01串当作一个点,每次通过操作i变成曾经未生成的状态,就相当于这两个状态之间连了一条权值为ci的边。为求最优解,可以通过记忆化搜索来扩展状态,dj来维护解的数组。

#include
#include
#include
#include
#include
#include
using namespace std;
#define NUM (1<<20)
#define INF 0x3f3f3f3f
struct node
{
    int num,cost;
    bool operator>(const node& x)const
    {
        return cost>x.cost;
    }
};
int L,nop,nw;
int c[32];
int mul2[21];
string op[32];
string s1,s2;
bool pd[NUM];
int dp[NUM];
queue  ans;
int getnum(string s)
{
    int num=0;
    for(int i=L-1;i>=0;--i)
        if(s[i]=='1')
            num+=(1<<(L-1-i));
    return num;
}
void solve(int st,int en)
{
    memset(pd,false,sizeof(pd));
    memset(dp,INF,sizeof(dp));
    priority_queue< node , vector , greater > q;
    int num1,pos;
    node x,y;
    x.num=st;
    x.cost=0;
    dp[st]=0;
    q.push(x);
    while(!q.empty())
    {
        x=q.top();
        q.pop();
        if(x.num==en)
        {
            ans.push(x.cost);
            return ;
        }
        if(pd[x.num])continue ;
        pd[x.num]=true;
        for(int i=0;idp[x.num]+c[i]&&!pd[num1])
            {
                y.num=num1;
                y.cost=dp[num1]=dp[x.num]+c[i];
                q.push(y);
            }
        }
    }
    ans.push(-1);
}
int main()
{
    int N;
    scanf("%d",&N);
    int num1,num2;
    mul2[0]=1;
    for(int i=1;i<=20;++i)
        mul2[i]=mul2[i-1]<<1;
    while(N--)
    {
        scanf("%d%d%d",&L,&nop,&nw);
        for(int i=0;i>op[i];
            scanf("%d",&c[i]);
        }
        for(int i=0;i>s1>>s2;
            num1=getnum(s1);num2=getnum(s2);
            solve(num1,num2);
        }
        for(int i=0;i

 

你可能感兴趣的:(最短路,记忆化搜索)