博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
UVA 10817 - Headmaster's Headache(三进制状压dp)
阅读量:5267 次
发布时间:2019-06-14

本文共 1643 字,大约阅读时间需要 5 分钟。

题目:

状态压缩的DP,dp[i][st]表示状态为st考虑后面i个人所有人最小花费,

因为每个科目有三种状态,可以用一个三进制数表示,

状态不是很多,所以可以把预先把每个数的三进制预处理出来,

决策为选和不选。

#include
using namespace std;const int maxs = 8;const int MAXSTA = 6561+5;const int maxn = 101;int base[maxs+1],trp[MAXSTA][maxs+1];int dp[maxn][MAXSTA];int tch[maxn],cost[maxn],sa;int s,m,n;const int INF = 0x3fffffff;void preDeal(){ base[0] = 1; for(int i = 1; i <= maxs; i++){ base[i] = 3*base[i-1]; } for(int i = 1; i < MAXSTA; i++){ int x = i, cnt = 0; while(x){ trp[i][cnt++] = x%3; x /= 3; } }}int dfs(int i,int st){ if(i == n) return st == sa? 0:INF; int &ans = dp[i][st]; if(~ans) return ans; ans = dfs(i+1,st); //int nst = st; for(int j = 0; j < s; j++){ if(trp[tch[i]][j] && trp[st][j] != 2){ st += base[j]; } } ans = min(ans,dfs(i+1,st)+cost[i]); return ans;}int work(){ sa = base[s]-1; int st = 0,sum = 0; for(int i = 0; i < m; i++){ int c; scanf("%d",&c); sum += c; while(getchar()!='\n'){ int sub = getchar()-'1'; int t = trp[st][sub] ; if(t != 2){ st += base[sub]; } } } for(int i = 0; i < n; i++){ scanf("%d",cost+i); tch[i] = 0; while(getchar()!='\n'){ tch[i] += base[getchar()-'1']; } } memset(dp,-1,sizeof(dp)); return sum + dfs(0,st);}int main(){ //freopen("in.txt","r",stdin); preDeal(); while(scanf("%d%d%d",&s,&m,&n),s){ printf("%d\n",work()); } return 0;}

 

转载于:https://www.cnblogs.com/jerryRey/p/4746428.html

你可能感兴趣的文章
数据库02 /MySQL基础数据类型以及多表之间建立联系
查看>>
Python并发编程04/多线程
查看>>
CF461B Appleman and Tree
查看>>
CF219D Choosing Capital for Treeland
查看>>
杂七杂八的小笔记本
查看>>
51Nod1353 树
查看>>
CF1215E Marbles
查看>>
.net Core 图片验证码 基于SkiaSharp实现
查看>>
fish redux 个人理解
查看>>
java 笔记一些
查看>>
BZOJ2339 HNOI2011卡农(动态规划+组合数学)
查看>>
octave基本操作
查看>>
排球计分程序重构(一)
查看>>
axure学习点
查看>>
WPF文本框只允许输入数字[转]
查看>>
dom4j 通用解析器,解析成List<Map<String,Object>>
查看>>
第一个项目--用bootstrap实现美工设计的首页
查看>>
使用XML传递数据
查看>>
TYVJ.1864.[Poetize I]守卫者的挑战(概率DP)
查看>>
基于CMMI的敏捷开发过程文档裁剪
查看>>