uestc 稳住GCD

DP

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstdlib>
 4 #include<cstring>
 5 #include<string>
 6 #include<queue>
 7 #include<algorithm>
 8 #include<map>
 9 #include<iomanip>
10 #include<climits>
11 #include<string.h>
12 #include<cmath>
13 #include<stdlib.h>
14 #include<vector>
15 #define INF 1e7
16 #define MAXN 111111
17 #define Mod 1000007
18 using namespace std;
19 typedef long long LL;
20
21 int dp[777][10010];
22 int a[777];
23 int n, g, i, j;
24
25 int gcd(int a, int b)
26 {
27     return b == 0 ? a : gcd(b,a%b);
28 }
29
30 void init()
31 {
32     g = 0;
33     for (i = 1; i <= n; ++i)
34         for (j = 0; j <= 10004; ++j)
35             dp[i][j] = Mod;
36 }
37 int main()
38 {
39     cin >> n;
40     init();
41     int maxi = 1;
42     for (i = 1; i <= n; ++i) {
43         cin >> a[i];
44         g = gcd(a[i],g);
45         maxi = max(maxi, a[i]);
46         dp[i][a[i]] = 1;
47     }
48     for (i = 2; i <= n; ++i) {
49         for (j = 0; j <= maxi; ++j) {
50             if (dp[i - 1][j] != Mod) {
51                 int gg = gcd(a[i],j);
52                 if (gg == j)
53                     dp[i][gg] = min(dp[i][gg], dp[i - 1][j]);
54                 else
55                     dp[i][gg] = min(dp[i][gg], dp[i - 1][j] + 1);
56             }
57         }
58     }
59     cout << n - dp[n][g] << endl;
60     return 0;
61 }
时间: 2024-10-20 03:42:12

uestc 稳住GCD的相关文章

UESTC 923 稳住GCD DP + GCD

定义:dp[i][j] 表示 在前i个数中,使整个gcd值为j时最少取的数个数. 则有方程: gg = gcd(a[i],j) gg == j : 添加这个数gcd不变,不添加,  dp[i][j] = dp[i-1][j] gg != j: t添加,更新答案,                dp[i][gg] = dp[i-1][j] + 1 最后答案为dp[n][g] (g为原始的所有数的gcd) 时间复杂度: O(n*max(a[i])) 代码: #include <iostream>

D - 稳住GCD DP

http://acm.uestc.edu.cn/#/problem/show/923 给定一堆数字,求其所有数字的gcd. 现在要删除最多的数字,使得剩下的数字的gcd和原来的一样. 设dp[i][val]表示在前i个数中,得到val这个数字所需的最小数字,怎么得到val这个数字?就是gcd得到. dp[i][gcd] 然后转移就是 dp[i][a[i]] = 1是必然的,自己一个 枚举新数字得到新的gcd  val dp[i][val] = min(dp[i][val], dp[i - 1][

UESTC - 1724 GCD区间求和

依然是神奇的欧拉函数 若GCD(n,i)=k 则GCD(n/k,i/k)=1, 令i/k=x,有GCD(n/k,x)=1, →k*GCD(n/k,x)=1中x的个数 = GCD(n,i)=k的和 范围就是求n的所有因子k #include<bits/stdc++.h> using namespace std; const int maxn = 1e6+11; typedef unsigned long long ll; ll phi[maxn]; void euler(int n){ for(

UESTC 288 青蛙的约会 扩展GCD

设两只青蛙跳了t步,则此时A的坐标:x+mt,B的坐标:y+nt.要使的他们在同一点,则要满足: x+mt - (y+nt) = kL (p是整数) 化成: (n-m)t + kL = x-y (L > 0)  则变成求解同余方程: (n-m)t ≡ (x-y) mod L  ,用扩展gcd解决. 且此时当 (x-y) % gcd(n-m,L) == 0 时才有解. 解同余方程ax+by = m时,假设我们已经求出了一对x0,y0,则 x0 = x*m/gcd(a,b) ,此时x0可能不是正整数

UESTC 1697 简单GCD问题(一) 筛法

简单GCD问题(一) Time Limit: 1500/500MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) 秦队长给你两个长度为nn的序列AA和BB,第ii个数分别为aiai和bibi请你求出∑1≤i,j≤ngcd(i,j)aibj∑1≤i,j≤ngcd(i,j)aibj的值答案可能很大,请输出模1e9+71e9+7后的结果 Input 第一行输入一个数n(1≤n≤100000)n(1≤n≤100000),表示序列长

UESTC 75 The Queen&#39;s New Necklaces

题意:一个项链的珠子的颜色有若干种.每种颜色的珠子个数为Ai.求有多少种不同的项链? 我们考虑,如果旋转i个珠子,那么会产生gcd(n,i)个循环节,每个循环节的大小我们假设为K,那么如果有一个颜色的数量不是K的倍数,那么必然没有置换过后等价的情况,然而,如果全部都是K的倍数,那么我们就相当于在gcd(n,i)个空位里面,每种颜色放入a[i]/K个的方案总数,这是一个简单的组合计数问题,方法大概就是c(n,m1)*c(n-m1,m2)*c(n-m1-m2,m3)*... ...,然后还要再除以n

UESTC 2014 Summer Training #19

A.UVALive 6161 去迟了,队友已经开始写了,应该是个水题,贴个队友代码 #include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<map> #include<set> #include<vector> #include<algorithm> #inclu

UESTC 2014 Summer Training #16 Div.2

虽然被刷了还是要继续战斗下去嗯...就是基础不好,难度相对较大 A.SPOJ AMR10A 点是顺时针给出的,可以在图上画画(脑补也行),连线x-a,x-b(x为选定的一个点,比如第一个点),就把所求面积分成了四部分,a-b左边部分是较容易求出来的, 三角形面积是直接可求,另外两个多边形面积是可以预处理出来的(多个三角形面积和) 反正我是沒想出來...看題解也理解半天,多邊形面積转化为三角形面积和 嗯嗯 #include <iostream> #include <cstdio> #

UESTC 电子科大专题训练 数据结构 D

UESTC 1584 题意:平面坐标上有n个怪物,每个怪物有一个rank值,代表x坐标和y坐标都不大于它本身的怪物数(不包括本身) 思路:对x y坐标从小到大排序,x优先排序,用数状数组计算y坐标小于它的数量 AC代码: #include "iostream" #include "string.h" #include "stack" #include "queue" #include "string" #i