UVA 10604(进制式dp)

来源:互联网 发布:现在淘宝做什么好 编辑:程序博客网 时间:2024/06/05 14:28

直接最多有6中化学药物。那么每种最多为10,且要表示改位存在要加1,采用十二进制,最大值在3000000左右,又可用状态比较少,使用记忆花搜索。

#include <cstdio>#include <iostream>#include <cstring>#include <algorithm>#include <cmath>#include <climits>#include <deque>using namespace std;const int maxk = 3501000;int d[maxk],f[7][7],mi[10],t[7][7],n;bool vis[maxk];int sub(int& num,int i){   num=num-mi[i];}int digit(int num,int i){  return (num/mi[i])%12;}int dp(int j,int num){  if(vis[j]) return d[j];  vis[j] = true;  if(num==1){     return d[j] = 0;  }  d[j] = 1e9;  for(int k=0;k<n;k++)     for(int g=0;g<n;g++){         int d1 = digit(j,k);         int d2 = digit(j,g);         int num1 = j;         if((k!=g&&d1>1&&d2>1)||(k==g&&d1>=3)){             sub(num1,k);             sub(num1,g);             num1=num1+mi[t[k][g]-1];             d[j]=min(d[j],dp(num1,num-1)+f[k][g]);         }     }  return d[j];}int main(){    mi[0] = 1;    for(int i=1;i<=7;i++) mi[i]=mi[i-1]*12;    int T;    scanf("%d",&T);    char str[100];    while(T--){      scanf("%d",&n);      for(int i=0;i<n;i++)        for(int j=0;j<n;j++){          scanf("%d %d",&t[i][j],&f[i][j]);      }      memset(vis,false,sizeof(vis));      int cnt[11] = {0};      int k,x;      scanf("%d",&k);      for(int i=1;i<=k;i++){        scanf("%d",&x);        cnt[x]++;      }      int sum = 0;      for(int i=n;i>=1;i--){         sum=sum*12+cnt[i]+1;      }      scanf("%s",str);      printf("%d\n",dp(sum,k));    }    return 0;}

0 0
原创粉丝点击