2016icpc沈阳 HDU 5955 Guessing the Dice Roll AC自动机 高斯消元
来源:互联网 发布:小学安全网络知识竞赛 编辑:程序博客网 时间:2024/04/27 14:38
题意:n个人每人一个长为L的只包含1-6的猜测序列,一直掷骰子直到结果出现某个人的猜测序列,该人获胜,求每人获胜概率
题解:随机过程里的马尔可夫过程的稳定状态,在AC自动机上做状态转移,
#include <iostream>#include <cstdio>#include <cctype>#include <algorithm>#include <cstring>#include <string>#include <cmath>#include <vector>#include <set>#include <stack>#include <sstream>#include <queue>#include <map>#include <functional>#include <bitset>#include <ctime>using namespace std;#define pb push_back#define mk make_pair#define ll long long#define ull unsigned long long#define pii pair<int, int>#define mk make_pair#define fi first#define se second#define ALL(A) A.begin(), A.end()#define rep(i,n) for(int (i)=0;(i)<(int)(n);(i)++)#define repr(i, n) for(int (i)=(int)(n);(i)>=0;(i)--)#define repab(i,a,b) for(int (i)=(int)(a);(i)<=(int)(b);(i)++)#define reprab(i,a,b) for(int (i)=(int)(a);(i)>=(int)(b);(i)--)#define sc(x) scanf("%d", &x)#define pr(x) printf("x:%d\n", x)#define fastio ios::sync_with_stdio(0), cin.tie(0)#define frein freopen("in.txt", "r", stdin)#define freout freopen("out.txt", "w", stdout)#define freout1 freopen("out1.txt", "w", stdout)#define lb puts("")#define lson ((rt<<1)+1)#define rson ((rt<<1)+2)#define mid ((l+r)/2)#define lmid (l+(r-l)/3)#define rmid (r-(r-l)/3)#define debug cout<<"???"<<endlconst double PI = 3.1415926535897932384626433;const ll mod = 2147493647;const int INF = 0x3f3f3f3f;const double eps = 1e-12;template<class T> T gcd(T a, T b){if(!b)return a;return gcd(b,a%b);}const int maxn = 120, sgm_sz = 6;struct Trie{ int ch[maxn][sgm_sz]; int val[maxn]; int last[maxn]; int f[maxn]; int val_id[maxn]; int sz; void init() { sz = 1; memset(ch[0], 0, sizeof(ch[0])); memset(val_id, 0, sizeof(val_id)); } int idx(char c) {return c - '1';} void Insert(char *s, int v) { int u = 0, len = strlen(s); for(int i = 0; i < len; i++){ int c = idx(s[i]); if(!ch[u][c]){ memset(ch[sz], 0, sizeof(ch[sz])); ch[u][c] = sz; val[sz++] = 0; } u = ch[u][c]; } val[u] = v; val_id[v] = u; } void getFail() { queue<int> q; last[0] = f[0] = 0; for(int i = 0; i < sgm_sz; i++){ int u = ch[0][i]; if(u){ f[u] = last[u] = 0; q.push(u); } } while(!q.empty()){ int p = q.front(); q.pop(); for(int i = 0; i < sgm_sz; i++){ int u = ch[p][i]; if(!u){ ch[p][i] = ch[f[p]][i]; continue; } q.push(u); int v = f[p]; while(v && !ch[v][i]) v = f[v]; f[u] = ch[v][i]; last[u] = val[f[u]] ? f[u] : last[f[u]]; } } } /*void find(char *s) { int len = strlen(s), u = 0; for(int i = 0; i < len; i++){ int c = idx(s[i]); u = ch[u][c]; if(val[u]) deal(u); else if(last[u]) deal(last[u]); } } void deal(int u) { if(u){ //TODO deal(last[u]); } }*/} ac;double a[maxn][maxn];int equ,var;//equ个方程,var个变量double x[maxn];//解集bool free_x[maxn];int n;int sgn(double x){ return (x>eps)-(x<-eps);}void print_a(){ for(int i = 0; i < equ; i++){ for(int j = 0; j <= var; j++){ printf("%.6f ", a[i][j]); }lb; }}void print_x(){ for(int i = 0; i < var; i++){ printf("x[%d]:%.6f\n",i,x[i]); }}void gauss_build(int equ_par, int var_par){ memset(a, 0, sizeof(a)); memset(x, 0, sizeof(x)); equ = equ_par; var = var_par; auto val = ac.val; auto ch = ac.ch; int sz = ac.sz; for(int i = 0; i < sz; i++){ a[i][i] += -1; if(val[i]) continue; for(int j = 0; j < sgm_sz; j++){ a[ch[i][j]][i] += 1.0/6; } } a[0][var] += -1.0;}// 高斯消元法解方程组(Gauss-Jordan elimination).(0表示无解,1表示唯一解,大于1表示无穷解,并返回自由变元的个数)int gauss(){ //多少个方程,多少个变量 int i,j,k; int max_r; // 当前这列绝对值最大的行. int col; // 当前处理的列. double temp; int free_x_num; int free_index; // 转换为阶梯阵. col = 0; // 当前处理的列. memset(free_x,true,sizeof(free_x)); for(k = 0; k<equ && col<var; k++, col++){ max_r = k; for(i = k+1; i < equ; i++){ if(sgn(fabs(a[i][col]) - fabs(a[max_r][col]))>0) max_r = i; } if(max_r != k){ // 与第k行交换. for(j = k; j < var+1; j++) swap(a[k][j], a[max_r][j]); } if(sgn(a[k][col]) == 0){ // 说明该col列第k行以下全是0了,则处理当前行的下一列. k--; continue; } for(i = k+1; i < equ; i++){ // 枚举要删去的行. if (sgn(a[i][col]) != 0){ temp = a[i][col]/a[k][col]; for(j = col; j < var+1; j++){ a[i][j] = a[i][j] - a[k][j]*temp; } } } } for(i = k; i < equ; i++){ if(sgn(a[i][col]) != 0) return 0; } if(k < var){ for(i = k-1; i >= 0; i--){ free_x_num = 0; for(j = 0; j < var; j++){ if(sgn(a[i][j]) != 0 && free_x[j]) free_x_num++,free_index=j; } if(free_x_num > 1) continue; temp = a[i][var]; for(j = 0; j < var; j++){ if(sgn(a[i][j])!=0 && j!=free_index) temp -= a[i][j]*x[j]; } x[free_index] = temp/a[i][free_index]; free_x[free_index] = 0; } return var-k; } for (i = var-1; i >= 0; i--){ temp = a[i][var]; for(j = i+1; j <var; j++){ if(sgn(a[i][j]) != 0) temp -= a[i][j]*x[j]; } x[i] = temp/a[i][i]; } return 1;}int main(){ //frein; //freout; int n,t,l; sc(t); while(t--){ ac.init(); sc(n); sc(l); char s[15]; for(int i = 1; i <= n; i++){ for(int j = 0; j < l; j++){ int k; sc(k); s[j] = '0'+k; } s[l] = '\0'; ac.Insert(s, i); } ac.getFail(); gauss_build(ac.sz, ac.sz); //print_a(); gauss(); //print_x(); for(int i = 1; i <= n; i++){ //printf("val_id[%d]:%d\n",i,ac.val_id[i]); printf("%.6f%c", x[ac.val_id[i]], (i==n)?'\n':' '); } }return 0;}
用高斯消元求解状态矩阵的稳态解
阅读全文
0 0
- 2016icpc沈阳 HDU 5955 Guessing the Dice Roll AC自动机 高斯消元
- HDU 5955 Guessing the Dice Roll AC自动机 高斯消元
- hdu 5955 Guessing the Dice Roll 概率DP,ac自动机,高斯消元 ★★
- hdu5955 Guessing the Dice Roll AC自动机+高斯消元
- hdu 5955 Guessing the Dice Roll
- HDU-5955-Guessing the Dice Roll
- Hdu 5955 Guessing the Dice Roll 概率DP+高斯消元
- Guessing the Dice Roll HDU
- hdu5955Guessing the Dice Roll AC自动机+高斯消元
- AC自动机+高斯消元求解线性方程--2016icpc沈阳H
- hdu5955Guessing the Dice Roll
- HDU 5955 AC自动机+高斯消元
- hdu 5955 (ac自动机+高斯消元 )
- hdu 5956 The Elder 2016ACM/ICPC沈阳赛区现场赛I
- Hdu 4057 Rescue the Rabbit (AC自动机+状态压缩dp) - 2011 ACM-ICPC Dalian Regional Contest Problem G
- 2017 ACM-ICPC 亚洲区(青岛赛区)网络赛 HDU 6208 1003 The Dominator of Strings(AC自动机)
- HDU 6194 后缀自动机(2017 ICPC沈阳网络赛A题)
- 2016ICPC-沈阳行
- mac版pycharm修改当前项目所用的python 版本
- jquery.lazyload.js 懒加载
- 第二次自考总结(淋雨一直走)
- java中级工程师需要掌握的技能
- Gym 101201.B
- 2016icpc沈阳 HDU 5955 Guessing the Dice Roll AC自动机 高斯消元
- list与json互转
- NOIP2011提高组-Car的旅行路线
- 数组去重
- 三顾茅庐:从刘备面试孔明得出的选股经验
- sed,awk多条件匹配
- 【Kalman】卡尔曼滤波Matlab简单实现
- Gym 101201.F
- jvm(三):对象引用与垃圾回收