【CF】259 Div.1 B Little Pony and Harmony Chest

还蛮有趣的一道状态DP的题目。

  1 /* 435B */
  2 #include <iostream>
  3 #include <string>
  4 #include <map>
  5 #include <queue>
  6 #include <set>
  7 #include <stack>
  8 #include <vector>
  9 #include <deque>
 10 #include <algorithm>
 11 #include <cstdio>
 12 #include <cmath>
 13 #include <ctime>
 14 #include <cstring>
 15 #include <climits>
 16 #include <cctype>
 17 #include <cassert>
 18 #include <functional>
 19 #include <iterator>
 20 #include <iomanip>
 21 using namespace std;
 22 //#pragma comment(linker,"/STACK:102400000,1024000")
 23
 24 #define sti                set<int>
 25 #define stpii            set<pair<int, int> >
 26 #define mpii            map<int,int>
 27 #define vi                vector<int>
 28 #define pii                pair<int,int>
 29 #define vpii            vector<pair<int,int> >
 30 #define rep(i, a, n)     for (int i=a;i<n;++i)
 31 #define per(i, a, n)     for (int i=n-1;i>=a;--i)
 32 #define clr                clear
 33 #define pb                 push_back
 34 #define mp                 make_pair
 35 #define fir                first
 36 #define sec                second
 37 #define all(x)             (x).begin(),(x).end()
 38 #define SZ(x)             ((int)(x).size())
 39 #define lson            l, mid, rt<<1
 40 #define rson            mid+1, r, rt<<1|1
 41
 42 const int maxn = 65;
 43 int mask[maxn];
 44 bool visit[maxn];
 45 int P[maxn];
 46 const int m = 16;
 47 const int N = (1<<m)+5;
 48 const int INF = 0x1f1f1f1f;
 49 int dp[105][N];
 50 int path[105][N];
 51 int a[105];
 52
 53 void init() {
 54     int i, j, k = 0;
 55
 56     for (i=2; i<maxn; ++i) {
 57         if (!visit[i]) {
 58             P[k++] = i;
 59             for (j=i*i; j<maxn; j+=i)
 60                 visit[j] = true;
 61         }
 62     }
 63
 64     for (i=1; i<maxn; ++i) {
 65         for (j=0; j<m; ++j) {
 66             if (i%P[j] == 0) {
 67                 mask[i] |= (1<<j);
 68             }
 69         }
 70     }
 71
 72     #ifndef ONLINE_JUDGE
 73         printf("P[%d] = %d\n", m, P[m]);
 74     #endif
 75 }
 76
 77 int main() {
 78     ios::sync_with_stdio(false);
 79     #ifndef ONLINE_JUDGE
 80         freopen("data.in", "r", stdin);
 81         freopen("data.out", "w", stdout);
 82     #endif
 83
 84     init();
 85     int n;
 86
 87     scanf("%d", &n);
 88     rep(i, 1, n+1)
 89         scanf("%d", &a[i]);
 90
 91     int i, j, k;
 92     int st, tmp;
 93     int mxs = 1<<16;
 94
 95     memset(dp, 0x1f, sizeof(dp));
 96     memset(dp[0], 0, sizeof(int)*N);
 97     for (i=1; i<=n; ++i) {
 98         for (j=0; j<mxs; ++j) {
 99             for (k=1; k<=60; ++k) {
100                 if (j & mask[k])
101                     continue;
102                 tmp = dp[i-1][j] + abs(a[i] - k);
103                 st = j | mask[k];
104                 if (dp[i][st] > tmp) {
105                     dp[i][st] = tmp;
106                     path[i][st] = k;
107                 }
108             }
109         }
110     }
111
112     int mn = INT_MAX, v;
113
114     for (j=0; j<mxs; ++j) {
115         if (dp[n][j] < mn) {
116             mn = dp[n][j];
117             v = j;
118         }
119     }
120
121     vi ans;
122
123     for (i=n; i>0; --i) {
124         k = path[i][v];
125         ans.pb(k);
126         v ^= mask[k];
127     }
128
129     for (i=n-1; i>=0; --i)
130         printf("%d ", ans[i]);
131     putchar(‘\n‘);
132
133     #ifndef ONLINE_JUDGE
134         printf("time = %d.\n", (int)clock());
135     #endif
136
137     return 0;
138 }
时间: 2024-11-03 02:35:31

【CF】259 Div.1 B Little Pony and Harmony Chest的相关文章

Codeforces Round #259 (Div. 2)-D. Little Pony and Harmony Chest

题目范围给的很小,所以有状压的方向. 我们是构造出一个数列,且数列中每两个数的最大公约数为1; 给的A[I]<=30,这是一个突破点. 可以发现B[I]中的数不会很大,要不然就不满足,所以B[I]<=60左右.构造DP方程DP[I][J]=MIN(DP[I][J],DP[I][J^C[K]]+abs(a[i]-k)); K为我们假设把这个数填进数组中的数.同时开相同空间记录位置,方便输出结果.. #include<iostream> #include<stdio.h>

Codeforces Round #259 (Div. 2) D. Little Pony and Harmony Chest 状压DP

D. Little Pony and Harmony Chest Princess Twilight went to Celestia and Luna's old castle to research the chest from the Elements of Harmony. A sequence of positive integers bi is harmony if and only if for every two elements of the sequence their gr

【CF】121 Div.1 C. Fools and Roads

题意是给定一棵树.同时,给定如下k个查询: 给出任意两点u,v,对u到v的路径所经过的边进行加计数. k个查询后,分别输出各边的计数之和. 思路利用LCA,对cnt[u]++, cnt[v]++,并对cnt[LCA(u, v)] -= 2.然后dfs求解各边的计数. 1 /* 191C */ 2 #include <iostream> 3 #include <string> 4 #include <map> 5 #include <queue> 6 #inc

【CF】207 Div.1 B.Xenia and Hamming

这题目一看很牛逼,其实非常easy.求求最小公倍数,最大公约数,均摊复杂度其实就是O(n). 1 /* 356B */ 2 #include <iostream> 3 #include <string> 4 #include <map> 5 #include <queue> 6 #include <set> 7 #include <stack> 8 #include <vector> 9 #include <dequ

【CF】196 Div.2 Book of Evil

显然这个图是一课树,看着题目首先联想到LCA(肯定是可以解的).但是看了一下数据大小,应该会TLE.然后,忽然想到一个前面做过的题目,大概是在一定条件下树中某结点旋转成为根后查询最长路径.结果灵感就来了,主要思路是对于每个结点,第一次dfs得到两个变量到P结点的最大值以及次大值.然后,第二次dfs对于当前结点u,u到它的子树中P类结点的最大距离已知(nd[u].mx),那么除u的其他结点v到P类结点的最大距离加上v到u的距离和的最大值为pmx,可以通过每次深搜计算出来,只要d大于等于两者的最大值

【CF】310 Div.1 C. Case of Chocolate

线段树的简单题目,做一个离散化,O(lgn)可以找到id.RE了一晚上,额,后来找到了原因. 1 /* 555C */ 2 #include <iostream> 3 #include <string> 4 #include <map> 5 #include <queue> 6 #include <set> 7 #include <stack> 8 #include <vector> 9 #include <dequ

【CF】110 Div.1 B. Suspects

这题目乍眼一看还以为是2-sat.其实很水的,O(n)就解了.枚举每个人,假设其作为凶手.观察是否满足条件.然后再对满足的数目分类讨论,进行求解. 1 /* 156B */ 2 #include <iostream> 3 #include <string> 4 #include <map> 5 #include <queue> 6 #include <set> 7 #include <stack> 8 #include <vec

【CF】174 Div.1 B Cow Program

思路是树形DP+状态压缩.其实仅有2个状态,奇数次来到x或者偶数次来到x.(因为对x的更新不同).同时开辟visit数组,解决环.注意,一旦遇到环结果就是-1.DP数组存放第奇数/偶数次来到x时,对y的改变两. 1 /* 283B */ 2 #include <iostream> 3 #include <string> 4 #include <map> 5 #include <queue> 6 #include <set> 7 #include

【CF】142 Div.1 B. Planes

SPFA.注意状态转移条件,ans的求解需要在bfs中间求解.因为只要到了地点n,则无需等待其他tourist.还是蛮简单的,注意细节. 1 /* 229B */ 2 #include <iostream> 3 #include <string> 4 #include <map> 5 #include <queue> 6 #include <set> 7 #include <stack> 8 #include <vector&g