UVA 10604(进制式dp)
2015-03-24 10:33
260 查看
直接最多有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; }
相关文章推荐
- uva 10604 Chemical Reaction (DP)
- Chemical Reaction - UVa 10604 dp
- dp(UVa 10604 - Chemical Reaction)
- uva 10604 - Chemical Reaction(状态压缩dp)
- uva 10604 化学药品链式dp
- uva 116 Unidirectional TSP (dp)
- UVA1625 / UVALive 5841 Color Length DP
- UVA 580 - Critical Mass(DP)
- uva 10271 (dp)
- uva 11825 - Hackers' Crackdown dp
- UVA 10037 Bridge (基础DP)
- Numbering Paths (Uva 125 floyd+dp思想)
- UVALive - 6952 Cent Savings (DP)
- UVA-10943(dp)
- UVA11270 轮廓线DP
- UVA 11468 - Substring (AC自动机 概率DP)
- UVA 10891 Game of Sum (博弈论 + 区间dp)
- UVA 662 Fast Food(dp)
- uva 1362 - Exploring Pyramids(区间dp)
- UVA 590 Always on the run(DP)