CF71E Nuclear Fusion

一、题目

点此看题

二、解法

n , k n,k 都很小,可以考虑状压,设 d p [ i ] [ s ] dp[i][s] 为完成目标数组的前 i i 个,需要用已有数组的状态为 s s ,状态数本来就不大,所以直接记忆化搜索即可。

复杂度我觉得应该是枚举子集的子集,所以是 O ( n 3 n ) O(n3^n) ,当然这只是上界,实际应该会快很多(搜索处剪枝)

#include <cstdio>
#include <vector>
#include <cstdlib>
#include <iostream>
using namespace std;
const int M = 20;
string s[]={" ","H","He","Li","Be","B","C","N","O","F","Ne","Na","Mg","Al","Si","P","S","Cl","Ar","K", "Ca", "Sc", "Ti", "V", "Cr", "Mn", "Fe", "Co", "Ni", "Cu","Zn" ,"Ga", "Ge", "As" ,"Se" ,"Br" ,"Kr" ,"Rb" ,"Sr" ,"Y" ,"Zr" ,"Nb", "Mo" ,"Tc" ,"Ru" ,"Rh" ,"Pd" ,"Ag" ,"Cd" ,"In" ,"Sn" ,"Sb" ,"Te" ,"I" ,"Xe" ,"Cs", "Ba" ,"La", "Ce" ,"Pr" ,"Nd" ,"Pm" ,"Sm", "Eu" ,"Gd", "Tb" ,"Dy" ,"Ho" ,"Er" ,"Tm" ,"Yb" ,"Lu", "Hf" ,"Ta", "W", "Re", "Os" ,"Ir" ,"Pt" ,"Au", "Hg", "Tl", "Pb", "Bi" ,"Po" ,"At", "Rn" ,"Fr", "Ra" ,"Ac" ,"Th" ,"Pa", "U" ,"Np", "Pu", "Am", "Cm", "Bk", "Cf", "Es" ,"Fm"};
int read()
{
 int x=0,f=1;char c;
 while((c=getchar())<'0' || c>'9') {if(c=='-') f=-1;}
 while(c>='0' && c<='9') {x=(x<<3)+(x<<1)+(c^48);c=getchar();}
 return x*f;
}
int n,m,a[M],b[M],f[M][1<<18];
string t;vector<int> v;
int work(string x)
{
    for(int i=1;i<=100;i++)
        if(s[i]==x) return i;
}
void print()
{
    int sum=0,j=0;
    for(int i=0;i<v.size();i++)
    {
        sum+=v[i];
        cout<<s[v[i]];
        if(sum==b[j])
        {
            printf("->");
            cout<<s[b[j++]];
            puts("");sum=0;
        }
        else printf("+");
    }
    exit(0);
}
void dfs(int x,int sum,int s)
{
    if(sum==b[x])
    {
        if(x==m)
        {
            puts("YES");
            print();
        }
        else dfs(x+1,0,s);
        return ;
    }
    if(sum>b[x]) return ;
    if(f[x][s]) return ;
    for(int i=0;i<n;i++)
    {
        if(s&(1<<i)) continue;
        v.push_back(a[i]);
        dfs(x,sum+a[i],s|(1<<i));
        v.pop_back();
    }
    f[x][s]=1;
}
signed main()
{
    n=read();m=read();
    for(int i=0;i<n;i++)
    {
        cin>>t;
        a[i]=work(t);
    }
    for(int i=0;i<m;i++)
    {
        cin>>t;
        b[i]=work(t);
    }
    dfs(0,0,0);
    puts("NO");
}

猜你喜欢

转载自blog.csdn.net/C202044zxy/article/details/107755734