hdu-3183A Magic Lamp(贪心)

题目的意思是:

给你一个大数,然后删减其中的K个数,并且剩下的数还是按原来在的先后次序排列,求所得的那个数最小的那个数。

思路:贪心(要取得数最小,你从左往右选数的时候,选的第一数,就是选后组成数的位权最高的,要一个数最小,位权最高的所对应那位要最小,然后依次是下一位权最小)。原来有N个数,删除K个数得最小数可以转化为从左往右选N-K个数所组成的数最小。那么第一个数必须在区间[0,K](数组下标)(存大数的数组首位是从0开始的)。

证:选的第一位数如果超过K,假如取的是K+S(K+S<=N-1)那么从(K+S+1)到N-1还剩下(N-K-S-1)个数,因为已经选了一个数剩余(N-K-1)个数没选,那么这些数必定要在区间

[K-S+1,N]上选。又(N-K-1)大于区间长度N-K-S-1(S>=1).

所以第一个数只能在[0,K]上取,且要取最小值,每位取当前区间最小才能保证最后所得数最小。

那么当第一个数取完后,取的是pos位置的,那么在[0,pos-1]是未取得数,也就是去掉的数,因为后面省下的(N-K-1)个数不能在这些位置去,因为这些数在pos之前,所以如果去的话

在所得的数中位置在第一个数之前,所以与pos为第一个数矛盾。

这样你选第二个数时此时K应该更新为K-(pos+1-n)(n为当前所选好的数的个数(当前n=1)),pos更新为pos+1;那么第二个数在区间[pos,pos+K]其实pos+K就为K+n;

那么这样直到选好N-K个数就行了。

 /*RMQ优化 复杂度为n*log(n)*/ 1 #include<stdio.h>
 2 #include<algorithm>
 3 #include<iostream>
 4 #include<stdlib.h>
 5 #include<string.h>
 6 #include<math.h>
 7 void RMQup(int k,int l);
 8 int que(int i,int j);
 9 int Min(int x,int y);
10 char a[2000];
11 int  b[2000];
12 const int N=100;
13 int RMQ[1005][1005];
14 using namespace std;
15 int main(void)
16 {
17     int n,i,j,k,p,q,l,m;
18     while(scanf("%s",a)!=EOF)
19     {
20         scanf("%d",&k);
21         l=strlen(a);
22         p=l-k;
23         for(i=0; i<l; i++)
24             RMQ[0][i]=i;
25         int r=log2(l);
26         r++;
27         RMQup(r,l);
28         int pp,qq;
29         int dd;
30         pp=0;
31         m=k;
32         int coutt =0;
33         while(coutt<p)//选好p个数字就结束
34         {
35             int z=que(pp,m);
36             b[coutt++]=a[z]-‘0‘;
37             pp=z+1;
38             m++;
39         }
40         for(i=0; i<p; i++)
41         {
42             if(b[i]!=0)
43             {
44                 break;
45             }
46         }
47         for(j=i; j<p; j++)
48         {
49             printf("%d",b[j]);
50         }
51         if(i==p)
52         {
53             printf("0");
54         }
55         printf("\n");
56     }
57
58     return 0;
59
60
61 }
62
63
64 void RMQup(int k,int l)//dp求RMQ(这种RMQ链接讲解http://www.cnblogs.com/zzuli2sjy/p/4971449.html)
65 {
66     int i,j;
67     for(i=1; i<=k; i++)
68         for(j=0; j<l; j++)
69             if(j+(1<<i-1)<l)
70                 RMQ[i][j]=Min(RMQ[i-1][j],RMQ[i-1][j+(1<<i-1)]);
71
72 }
73
74 int que(int i,int j)
75 {
76     int f=log2(j-i+1);
77     return Min(RMQ[f][i],RMQ[f][j-(1<<f)+1]);
78
79 }
80 int Min(int x,int y)//求在某段的最小值的数组下标
81 {
82     if(a[x]==a[y])
83     {
84         return x<y?x:y;//当两个数相同时返回数组下标小的(比如223 要去1个数字,答案是22,如果返回数组下标大的结果就是23了)
85     }
86     else
87     {
88         return a[x]<a[y]?x:y;
89     }
90 }
 1 /*直接循环找段最小*/
 2 #include<stdio.h>
 3 #include<algorithm>
 4 #include<iostream>
 5 #include<stdlib.h>
 6 #include<string.h>
 7 using namespace std;
 8 char a[1005];
 9 char b[1005];
10 int main(void)
11 {
12     int n,i,j,k,p,q,l;
13     while(scanf("%s",a)!=EOF)
14     {
15         scanf("%d",&k);
16         l=strlen(a);
17         if(k==l)
18         {
19             printf("0\n");
20         }
21         else
22         {
23             int y=l-k;
24             int x=0;
25             int m=y;
26             int coutt=0;
27             int dd;
28             dd=0;
29             while(coutt<y)
30             {
31                 b[coutt]=a[x];
32                 for(i=x; i<=x+k; i++)//循环找最小
33                 {
34                     if(a[i]<b[coutt])
35                     {
36                         b[coutt]=a[i];
37                         dd=i;
38                     }
39
40                 }
41                 dd=dd+1;
42                 k-=(dd-x-1);
43                 coutt++;
44                 x=dd;
45             }
46             for(i=0; i<coutt; i++)
47             {
48                 if(b[i]!=‘0‘)
49                 {
50                     break;
51                 }
52             }
53             if(i==coutt)
54             {
55                 printf("0");
56             }
57             for(j=i; j<coutt; j++)
58             {
59                 printf("%c",b[j]);
60             }
61             printf("\n");
62         }
63     }
64     return 0;
65 }
时间: 2024-08-11 05:29:09

hdu-3183A Magic Lamp(贪心)的相关文章

HDU 3183 A Magic Lamp(贪心+RMQ)

Description Kiki likes traveling. One day she finds a magic lamp, unfortunately the genie in the lamp is not so kind. Kiki must answer a question, and then the genie will realize one of her dreams. The question is: give you an integer, you are allowe

HDU_3183_A Magic Lamp(贪心)

A Magic Lamp Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2274    Accepted Submission(s): 902 Problem Description Kiki likes traveling. One day she finds a magic lamp, unfortunately the geni

hdu A Magic Lamp

http://acm.hdu.edu.cn/showproblem.php?pid=3183 A Magic Lamp Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 2556    Accepted Submission(s): 999 Problem Description Kiki likes traveling. One day

hdu 3183 A Magic Lamp (贪心)

///给你一数字,删除其中的m位使其最小 ///贪心:前面的数要小于后面的数 # include <stdio.h> # include <algorithm> # include <iostream> # include <string.h> # include <math.h> using namespace std; char str[1010]; int a[1010]; int c[1010]; int main() { int k,m

hdu 3183 A Magic Lamp(RMQ)

A Magic Lamp                                                                               Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Problem Description Kiki likes traveling. One day she finds a magic lamp, u

A Magic Lamp(贪心)

A Magic Lamp Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 2521    Accepted Submission(s): 986 Problem Description Kiki likes traveling. One day she finds a magic lamp, unfortunately the genie

hdu 3183 A Magic Lamp(RMQ)

题目链接:hdu 3183 A Magic Lamp 题目大意:给定一个字符串,然后最多删除K个,使得剩下的组成的数值最小. 解题思路:问题等价与取N-M个数,每次取的时候保证后面能取的个数足够,并且取的数最小,查询最小的操作用RMQ优化. #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn = 10005; int N, M, d[m

hdu 3183 A Magic Lamp rmq或者暴力

A Magic Lamp Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Problem Description Kiki likes traveling. One day she finds a magic lamp, unfortunately the genie in the lamp is not so kind. Kiki must answer a question

HDU 3183 A Magic Lamp(RMQ问题, ST算法)

原题目 A Magic Lamp Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 3964    Accepted Submission(s): 1605 Problem Description Kiki likes traveling. One day she finds a magic lamp, unfortunately the

hdu 4296 Buildings(贪心)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4296 Buildings Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1822    Accepted Submission(s): 722 Problem Description Have you ever heard the sto