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
  • 相关阅读:
    c语言程序设计(学生成绩管理系统)————提供给计算机系c语言初学者参考
    C语言之指针排序
    C语言之冒泡法一
    C语言之统计字符
    C语言之while输出菱形
    C语言之do_while输出菱形
    C语言之素数的判断
    C语言之输出菱形
    基于RT-THREAD的定时鱼缸喂食器设计
    dx/dy=1/y’求其二阶导
  • 原文地址:https://www.cnblogs.com/fjmmm/p/3828482.html
Copyright © 2011-2022 走看看