zoukankan      html  css  js  c++  java
  • 20140705 testC DP

    testC

    输入文件: testC.in  输出文件testC.out 时限1000ms

    问题描述:

    给你一组数,a1,a2,a3,⋯,an

    令:G=gcd(a1,a2,a3,⋯,an)

    现在从中任意删除一些数字,设剩下的数为:al1,al2,al3,⋯,alm

    再令:g=gcd(al1,al2,al3,⋯,alm)

    现要求G=g,问最多能删除多少数?

    输入描述:

    第一行一个数n,第二行n个数a1,a2,a3,⋯,an

    1≤n≤700

    1≤ai≤10000

    输出描述:

    输出只有一个数,表示最多能删除多少数。

    样例输入:

    3
    4 6 8

    样例输出:

    1


    考试的时候觉得似乎答案只有n-1 n-2 0 三种情况
    后来仔细想想发现不是这样 >_<
    正解是dp
    dp[i]表示最大公倍数为i最少需要多少数
    转移方程
    dp[gcd(i,a[k])] = min(dp[gcd(i,a[k])],dp[i]+1)
    答案便是 n-dp[G]

     1 #include <cstdio>
     2 #include <cstring>
     3 using namespace std;
     4 #define MAX_num 10010
     5 #define INF 0x3f3f3f
     6 
     7 int gcd(int a,int b) {
     8     if (a%b==0) return b;
     9     return gcd(b,a%b);
    10 }
    11 
    12 int min(int a,int b) {
    13     return a<b?a:b;
    14 }
    15 
    16 int n;
    17 int dp[MAX_num];
    18 
    19 int main() {
    20     scanf("%d",&n);
    21     memset(dp,INF,sizeof(dp));
    22     int x;
    23     scanf("%d",&x);
    24     int G=x;
    25     dp[x]=1;
    26     for (int i=2;i<=n;i++) {
    27         scanf("%d",&x);
    28         dp[x]=1;
    29         G=gcd(G,x);
    30         for (int j=1;j<MAX_num;j++) {
    31             int g=gcd(j,x);
    32             dp[g]=min(dp[g],dp[j]+1);
    33         }
    34     }
    35     printf("%d",n-dp[G]);
    36 }
    View Code
  • 相关阅读:
    Nginx 反向代理接收用户包体方式
    Nginx http反向代理流程Proxy_pass模块
    Nginx 负载均衡一致性算法
    Nginx 负载均衡哈希算法:ip_hash与hash模块
    Nginx upstream模块
    Nginx upstream变量
    Nginx 反向代理与负载均衡基本原则
    19 浏览器缓存
    6 Cookie和Session
    5 Post和Get
  • 原文地址:https://www.cnblogs.com/fjmmm/p/3828482.html
Copyright © 2011-2022 走看看