日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

LOJ #3217. 「PA 2019」Desant(状压dp)

發布時間:2024/1/3 综合教程 24 生活家
生活随笔 收集整理的這篇文章主要介紹了 LOJ #3217. 「PA 2019」Desant(状压dp) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

https://loj.ac/problem/3217

考慮已經確定了前i個,狀態可以只記后面的(n-i)個點之間的(n-i+1)個間隔里的已選的數。

這個狀態最大是(sum_{k=1}^n (n/k)^k)左右,可以發現不是很大。

注意要用多進制數去存狀態,不然會被卡常。

Code:

#include<bits/stdc++.h>
#define fo(i, x, y) for(int i = x, _b = y; i <= _b; i ++)
#define ff(i, x, y) for(int i = x, _b = y; i <  _b; i ++)
#define fd(i, x, y) for(int i = x, _b = y; i >= _b; i --)
#define ll long long
#define pp printf
#define hh pp("
")
using namespace std;

const int N = 45;

int n, a[N];

int b[N], b0;

struct nod {
	ll w0, w[N];
} p, q;

void build(int *b, int &b0, nod &p) {
	sort(b + 1, b + b0 + 1);
	b[0] = 0; b[b0 + 1] = n + 1;
	p.w0 = b0;
	p.w[0] = 1;
	fo(j, 1, b0 + 1) p.w[j] = p.w[j - 1] * (b[j] - b[j - 1]);
}

void zh(int *a, nod b, int x) {
	fo(i, 0, b.w0) a[i] = x % b.w[i + 1] / b.w[i];
}

int zy(int *a, nod b) {
	int s = 0;
	fo(i, 0, b.w0) s += a[i] * b.w[i];
	return s;
}

struct P {
	int x; ll y;
	P(int _x = 0, ll _y = 0) {
		x = _x, y = _y;
	}
};

P operator + (P a, P b) {
	return a.x == b.x ? P(a.x, a.y + b.y) : (a.x < b.x ? a : b);
}

vector<P> f[N];

int main() {
	freopen("a.in", "r", stdin);
	scanf("%d", &n);
	fo(i, 1, n) scanf("%d", &a[i]);
	
	f[0].resize(1);
	f[0][0] = P(0, 1);
	
	fo(i, 0, n - 1) {
		b0 = 0;
		fo(j, i + 1, n) b[++ b0] = a[j];
		build(b, b0, p);
		int id; fo(j, 1, b0) if(b[j] == a[i + 1]) id = j;
			
		b0 = 0;
		fo(j, i + 2, n)	b[++ b0] = a[j];
		build(b, b0, q);
		
		int m1 = p.w[p.w0 + 1], m2 = q.w[q.w0 + 1];
		
		f[i + 1].resize(m2);
		ff(k, 0, m2) f[i + 1][k] = P(1e9, 0);
		
		ff(k, 0, m1) if(f[i][k].y) {
			static int c[N], d[N];
			zh(c, p, k);
			fo(cho, 0, 1) {
				P v = f[i][k];
				if(cho) {
					fo(u, id, p.w0) v.x += c[u];
				}
				int t = -1;
				fo(u, 0, p.w0) {
					if(u == id) {
						d[t] += c[u] + cho;
					} else d[++ t] = c[u];
				}
				int nk = zy(d, q);
				f[i + 1][nk] = f[i + 1][nk] + v;
			}
		}
	}

	static P ans[N];
	fo(i, 1, n) ans[i] = P(1e9, 0);	
	ff(k, 0, f[n].size()) {
		static int c[N];
		zh(c, q, k);
		int x = 0;
		fo(u, 0, q.w0) x += c[u];
		ans[x] = ans[x] + f[n][k];
	}
	fo(i, 1, n) pp("%d %lld
", ans[i].x, ans[i].y);
}

總結

以上是生活随笔為你收集整理的LOJ #3217. 「PA 2019」Desant(状压dp)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。