• 贪心入门题


    1.hdu 1009 FatMouse' Trade

    题目传送门[戳我]

    题解传送门[戳我]


    2.删数问题

    题目&评测传送门[戳我]

    PS

    题解:

      通过贪心的策略来想,应该是每一次选择局部最优解。

      这个局部最优解就是使当前的数最小,所以可以从高位到低位进行查找,使得s[j + 1] >= s[j]否则,删掉第j个数

    Code

     1 /**
     2  * smartoj
     3  * Problem#1098
     4  * Accepted
     5  * Time:107ms
     6  * Memory:516k 
     7  */
     8 #include<iostream>
     9 #include<cstdio>
    10 #include<cctype>
    11 #include<cstring>
    12 #include<cstdlib>
    13 #include<cmath>
    14 #include<fstream>
    15 #include<sstream>
    16 #include<algorithm>
    17 #include<map>
    18 #include<set>
    19 #include<queue>
    20 #include<vector>
    21 #include<stack>
    22 using namespace std;
    23 typedef bool boolean;
    24 #define INF 0xfffffff
    25 #define smin(a, b) a = min(a, b)
    26 #define smax(a, b) a = max(a, b)
    27 template<typename T>
    28 inline void readInteger(T& u){
    29     char x;
    30     int aFlag = 1;
    31     while(!isdigit((x = getchar())) && x != '-');
    32     if(x == '-'){
    33         x = getchar();
    34         aFlag = -1;
    35     }
    36     for(u = x - '0'; isdigit((x = getchar())); u = (u << 1) + (u << 3) + x - '0');
    37     ungetc(x, stdin);
    38     u *= aFlag;
    39 }
    40 
    41 vector<char> str;
    42 int s;
    43 
    44 inline void init(){
    45     char x;
    46     while((x = getchar()) != '
    '){
    47         str.push_back(x);
    48     }
    49     readInteger(s);
    50 }
    51 
    52 inline void solve(){
    53     for(int i = 1; i <= s; i++){
    54         int j = 0;
    55         while(j < (signed)str.size() - 1 && str[j + 1] >= str[j]){
    56             j++;    
    57         }
    58         str.erase(str.begin() + j);
    59     }
    60     int i = 0;
    61     while(i < str.size() && str[i] == '0') i++;
    62     for(; i < str.size(); i++){
    63         putchar(str[i]);
    64     }
    65 }
    66 
    67 int main(){
    68     init();
    69     solve();
    70     return 0; 
    71 }
    删数问题

    3.hdu 1045 Fire Net

    题目传送门[戳我]

    题解:

      一个很神奇的方法AC,按如果在(x, y)这个地方建城堡造成的影响数排序,然后for循环一边,把能建的都建,然后输出结果。

    Code

      1 /**
      2  * acm.hdu.com.cn
      3  * Problem#1045
      4  * Accepted
      5  * Time:15ms
      6  * Memory:1568k
      7  */
      8 #include<iostream>
      9 #include<cstdio>
     10 #include<cctype>
     11 #include<cstring>
     12 #include<cstdlib>
     13 #include<cmath>
     14 #include<fstream>
     15 #include<sstream>
     16 #include<algorithm>
     17 #include<map>
     18 #include<set>
     19 #include<queue>
     20 #include<vector>
     21 #include<stack>
     22 using namespace std;
     23 typedef bool boolean;
     24 #define INF 0xfffffff
     25 #define smin(a, b) a = min(a, b)
     26 #define smax(a, b) a = max(a, b)
     27 template<typename T>
     28 inline void readInteger(T& u){
     29     char x;
     30     int aFlag = 1;
     31     while(!isdigit((x = getchar())) && x != '-');
     32     if(x == '-'){
     33         x = getchar();
     34         aFlag = -1;
     35     }
     36     for(u = x - '0'; isdigit((x = getchar())); u = (u << 1) + (u << 3) + x - '0');
     37     ungetc(x, stdin);
     38     u *= aFlag;
     39 }
     40 
     41 int n;
     42 int f[5][5];
     43 
     44 inline boolean init(){
     45     readInteger(n);
     46     if(n == 0)    return false;
     47     for(int i = 1; i <= n; i++){
     48         getchar();
     49         for(int j = 1; j <= n; j++){
     50             char x = getchar();
     51             if(x == 'X')
     52                 f[i][j] = 1;
     53             else f[i][j] = 0;
     54         }
     55     }
     56     return true;
     57 }
     58 
     59 int roles[5][5];
     60 
     61 void fire(int x, int y){
     62     for(int i = x - 1; i >= 1 && f[i][y] == 0; i--){        roles[x][y]++;    }
     63     for(int i = x + 1; i <= n && f[i][y] == 0; i++){        roles[x][y]++;    }
     64     for(int j = y - 1; j >= 1 && f[x][j] == 0; j--){        roles[x][y]++;    }
     65     for(int j = y + 1; j <= n && f[x][j] == 0; j++){        roles[x][y]++;    }
     66 }
     67 
     68 typedef class Data{
     69     public:
     70         int x, y;
     71         int data;
     72         Data(const int x = 0, const int y = 0, const int data = 0):x(x), y(y), data(data){}
     73 }Data;
     74 
     75 boolean cmpare(const Data& a, const Data& b){
     76     return a.data < b.data;
     77 }
     78 
     79 vector<Data> l;
     80 boolean visited[5][5];
     81 inline void solve(){
     82     memset(roles, 1, sizeof(roles));
     83     memset(visited, false, sizeof(visited));
     84     for(int i = 1; i <= n; i++){
     85         for(int j = 1; j <= n; j++){
     86             if(f[i][j] == 0){
     87                 fire(i, j);
     88                 l.push_back(Data(i, j, roles[i][j]));
     89             }
     90         }
     91     }
     92     sort(l.begin(), l.end(), cmpare);
     93     int result = 0;
     94     for(int k = 0; k < (signed)l.size(); k++){
     95         if(!visited[l[k].x][l[k].y]){
     96             result++;
     97             int &x = l[k].x, &y= l[k].y;
     98             for(int i = x - 1; i >= 1 && f[i][y] == 0; i--){        visited[i][y] = true;    }
     99             for(int i = x + 1; i <= n && f[i][y] == 0; i++){        visited[i][y] = true;    }
    100             for(int j = y - 1; j >= 1 && f[x][j] == 0; j--){        visited[x][j] = true;    }
    101             for(int j = y + 1; j <= n && f[x][j] == 0; j++){        visited[x][j] = true;    }
    102         }
    103     }
    104     l.clear();
    105     printf("%d
    ", result);
    106 }
    107 
    108 int main(){
    109     while(init()){
    110         solve();
    111     }
    112     return 0;
    113 }
    Fire Net

    4.hdu 1050 Moving Table

    题目传送门[戳我]

    题解:

      还是很神奇的方法,用差分,标记每次移动影响的范围,前缀和完了找出一个最大值乘10。因为不同地方可以同时进行,只有有地方重叠的时候需要分批扮桌子。

    Code

     1 /**
     2  * acm.hdu.com.cn
     3  * Problem#1050
     4  * Accepted
     5  * Time:0ms
     6  * Memory:1552k
     7  */
     8 #include<iostream>
     9 #include<cstdio>
    10 #include<cctype>
    11 #include<cstring>
    12 #include<cstdlib>
    13 #include<fstream>
    14 #include<sstream>
    15 #include<algorithm>
    16 #include<map>
    17 #include<set>
    18 #include<queue>
    19 #include<vector>
    20 #include<stack>
    21 #include<cmath>
    22 using namespace std;
    23 typedef bool boolean;
    24 #define INF 0xfffffff
    25 #define smin(a, b) a = min(a, b)
    26 #define smax(a, b) a = max(a, b)
    27 template<typename T>
    28 inline void readInteger(T& u){
    29     char x;
    30     int aFlag = 1;
    31     while(!isdigit((x = getchar())) && x != '-');
    32     if(x == '-'){
    33         x = getchar();
    34         aFlag = -1;
    35     }
    36     for(u = x - '0'; isdigit((x = getchar())); u = (u << 1) + (u << 3) + x - '0');
    37     ungetc(x, stdin);
    38     u *= aFlag;
    39 }
    40 
    41 int T;
    42 int n;
    43 int used[205];
    44 
    45 inline void init(){
    46     readInteger(n);
    47     for(int i = 1, a, b, c, d; i <= n; i++){
    48         readInteger(a);
    49         readInteger(b);
    50         c = (min(a, b) + 1) >> 1;
    51         d = (max(a, b) + 1) >> 1;
    52         used[c] += 1, used[d + 1] -= 1;
    53     }
    54 }
    55 
    56 inline void solve(){
    57     int result = 0;
    58     for(int i = 1; i <= 201; i++){
    59         used[i] += used[i - 1];
    60         smax(result, used[i]);
    61     }
    62     printf("%d
    ", result * 10);
    63     memset(used, 0, sizeof(used));
    64 }
    65 
    66 int main(){
    67     readInteger(T);
    68     while(T--){
    69         init();
    70         solve();
    71     }
    72     return 0;
    73 }
    Moving Table

    5.hdu 1051 Wooden Sticks

    题目传送门[here]

    题解:

      当成一个二元组排个序,然后每次往后找,保证每次找到的都不需要准备时间,每次循环完了将准备时间加1,前面最大的weight清0

    Code

     1 /**
     2  * acm.hdu.com.cn
     3  * Problem#1051
     4  * Accepted
     5  * Time:15ms
     6  * Memory:1644k
     7  */
     8 #include<iostream>
     9 #include<cstdio>
    10 #include<cctype>
    11 #include<cstring>
    12 #include<cstdlib>
    13 #include<cmath>
    14 #include<fstream>
    15 #include<sstream>
    16 #include<algorithm>
    17 #include<map>
    18 #include<set>
    19 #include<queue>
    20 #include<vector>
    21 #include<stack>
    22 using namespace std;
    23 typedef bool boolean;
    24 #define INF 0xfffffff
    25 #define smin(a, b) a = min(a, b)
    26 #define smax(a, b) a = max(a, b)
    27 template<typename T>
    28 inline void readInteger(T& u){
    29     char x;
    30     int aFlag = 1;
    31     while(!isdigit((x = getchar())) && x != '-');
    32     if(x == '-'){
    33         x = getchar();
    34         aFlag = -1;
    35     }
    36     for(u = x - '0'; isdigit((x = getchar())); u = (u << 1) + (u << 3) + x - '0');
    37     ungetc(x, stdin);
    38     u *= aFlag;
    39 }
    40 
    41 typedef class Stick{
    42     public:
    43         int length;
    44         int weight;
    45         Stick(const int length = 0, const int weight = 0):length(length), weight(weight){    }
    46         boolean operator <(Stick another) const {
    47             if(this->length != another.length)    return this->length < another.length;
    48             return this->weight < another.weight;
    49         }
    50 }Stick;
    51 
    52 int T;
    53 int n;
    54 Stick *ss;
    55 
    56 inline void init(){
    57     readInteger(n);
    58     ss = new Stick[(const int)(n + 1)];
    59     for(int i = 1; i <= n; i++){
    60         readInteger(ss[i].length);
    61         readInteger(ss[i].weight);
    62     }
    63 }
    64 
    65 boolean *visited;
    66 inline void solve(){
    67     int finished = 0;
    68     int result = 0, last;
    69     sort(ss + 1, ss + n + 1);
    70     visited = new boolean[(const int)(n + 1)];
    71     memset(visited, false, sizeof(boolean) * (n + 1));
    72     while(finished < n){
    73         result++;
    74         last = 0;
    75         for(int i = 1; i <= n; i++){
    76             if(!visited[i] && ss[i].weight >= last){
    77                 finished++;
    78                 visited[i] = true;
    79                 last = ss[i].weight;
    80             }
    81         }
    82     }
    83     printf("%d", result);
    84     delete[] ss;
    85     delete[] visited;
    86 }
    87 
    88 int main(){
    89     readInteger(T);
    90     while(T--){
    91         init();
    92         solve();
    93         putchar('
    ');
    94     }
    95     return 0;
    96 }
    Wooden Stacks

    6.UVa 10755 Garbage Heap

    原题传送门[here]

    VJudge传送门:[here]

    题解:

      首先降低维数,枚举x1, x2, y1, y2,然后可以将这一段压缩成一维的一段。然后就可以贪心了,为了让z1 - z2这一段竟可能大,所以应该使s[z2] - s[z1 - 1]尽可能小。然后加个前缀和降低时间复杂度,就可以开开心心地交vjudge了

      1 /**
      2  * uva
      3  * Problem#10755
      4  * Accepted
      5  * Time:180ms
      6  */
      7 #include<iostream>
      8 #include<cstdio>
      9 #include<cctype>
     10 #include<cstring>
     11 #include<cstdlib>
     12 #include<cmath>
     13 #include<fstream>
     14 #include<sstream>
     15 #include<algorithm>
     16 #include<map>
     17 #include<set>
     18 #include<queue>
     19 #include<vector>
     20 #include<stack>
     21 using namespace std;
     22 typedef bool boolean;
     23 #define INF 0xfffffff
     24 #define smin(a, b) a = min(a, b)
     25 #define smax(a, b) a = max(a, b)
     26 template<typename T>
     27 inline void readInteger(T& u){
     28     char x;
     29     int aFlag = 1;
     30     while(!isdigit((x = getchar())) && x != '-');
     31     if(x == '-'){
     32         x = getchar();
     33         aFlag = -1;
     34     }
     35     for(u = x - '0'; isdigit((x = getchar())); u = (u << 1) + (u << 3) + x - '0');
     36     ungetc(x, stdin);
     37     u *= aFlag;
     38 }
     39 
     40 const long long inf = (1LL << 60);
     41 
     42 template<typename T>
     43 inline void putInteger(T u){
     44     if(u == 0){
     45         putchar('0');
     46         return;
     47     }
     48     if(u < 0){
     49         putchar('-');
     50         u *= -1;
     51     }
     52     stack<char>    s;
     53     while(u != 0)    s.push(u % 10 + '0'), u /= 10;
     54     while(!s.empty())    putchar(s.top()), s.pop();
     55 }
     56 
     57 void expand(int i, int& x, int& y, int& z, int& sign){    //容斥原理 
     58     x = i & 1, i >>= 1;
     59     y = i & 1, i >>= 1;
     60     z = i & 1;
     61     sign = ((x + y + z) % 2 == 1) ? (1) : (-1);
     62 }
     63 
     64 int T;
     65 int a, b, c;
     66 
     67 long long s[21][21][21];
     68 inline void init_sum(){
     69     for(int i = 1; i <= a; i++){
     70         for(int j = 1; j <= b; j++){
     71             for(int k = 1; k <= c; k++){
     72                 for(int p = 1; p < 8; p++){
     73                     int x, y, z, sign;
     74                     expand(p, x, y, z, sign);
     75                     s[i][j][k] += s[i - x][j - y][k - z] * sign;
     76                 }
     77             }
     78         }
     79     }
     80 }
     81 
     82 //long long f[21];
     83 inline long long dp(int x1, int x2, int y1, int y2){
     84     long long sumz;
     85     long long result = -inf;
     86     long long minv = 0;
     87     int dx = x2 - x1 + 1, dy = y2 - y1 + 1;
     88     for(int i = 1; i <= c; i++){
     89         sumz = s[x2][y2][i];
     90         for(int p = 1; p < 8; p++){
     91             int x, y, z, sign;
     92             expand(p, x, y, z, sign);
     93             //sumz -= s[x2 - x * dx][y2 - y * dy][i - z] * sign;
     94             sumz -= s[x2 - x * dx][y2 - y * dy][i - z * i] * sign;
     95         }
     96         smax(result , sumz - minv);
     97         smin(minv, sumz);
     98 //        f[i] = max(0LL, f[i - 1]) + sumz;
     99 //        smax(result, f[i]);
    100     }
    101     return result;
    102 }
    103 
    104 inline void init(){
    105     readInteger(a);
    106     readInteger(b);
    107     readInteger(c);
    108     memset(s, 0, sizeof(s));
    109     for(int i = 1; i <= a; i++){
    110         for(int j = 1; j <= b; j++){
    111             for(int k = 1; k <= c; k++){
    112                 readInteger(s[i][j][k]);
    113             }
    114         }
    115     }
    116 }
    117 
    118 inline void solve(){
    119     long long result = -inf;
    120     for(int x1 = 1; x1 <= a; x1++){
    121         for(int x2 = x1; x2 <= a; x2++){
    122             for(int y1 = 1; y1 <= b; y1++){
    123                 for(int y2 = y1; y2 <= b; y2++){
    124                     long long cmp = dp(x1, x2, y1, y2);
    125                     smax(result, cmp);
    126                 }
    127             }
    128         }
    129     }
    130     putInteger(result);
    131     putchar('
    ');
    132 }
    133 
    134 int main(){
    135     readInteger(T);
    136     while(T--){
    137         init();
    138         init_sum();
    139         solve();
    140         if(T)    putchar('
    ');
    141     }
    142     return 0;
    143 }
    Garbage Heap

    7.USACO 1.3 Mixing Milk

    原题传送门[here]

    题目大意:

      一个公司需要购买N个单位的牛奶,有M个农民每天提供定价定量的牛奶。第i个农民的牛奶每个单位售价为Pi,每天提供Ai个单位的牛奶。求每天最小的开销。

    题解:

      和第一道题有些相似,按照单价排序,然后计算结果就行了。

     1 /*
     2 ID: m1582851
     3 PROG: milk
     4 LANG: C++11
     5 */
     6 /**
     7  * USACO
     8  * Accepted
     9  * Time:0ms
    10  * Memory:4184k
    11  */
    12 #include<iostream>
    13 #include<cstdio>
    14 #include<cctype>
    15 #include<cstring>
    16 #include<cstdlib>
    17 #include<fstream>
    18 #include<sstream>
    19 #include<algorithm>
    20 #include<map>
    21 #include<set>
    22 #include<queue>
    23 #include<vector>
    24 #include<stack>
    25 using namespace std;
    26 typedef bool boolean;
    27 #define INF 0xfffffff
    28 #define smin(a, b) a = min(a, b)
    29 #define smax(a, b) a = max(a, b)
    30 template<typename T>
    31 inline void readInteger(T& u){
    32     char x;
    33     int aFlag = 1;
    34     while(!isdigit((x = getchar())) && x != '-');
    35     if(x == '-'){
    36         x = getchar();
    37         aFlag = -1;
    38     }
    39     for(u = x - '0'; isdigit((x = getchar())); u = (u << 1) + (u << 3) + x - '0');
    40     ungetc(x, stdin);
    41     u *= aFlag;
    42 }
    43 
    44 typedef class Milk{
    45     public:
    46         int weight;
    47         int cost;
    48         Milk(const int weight = 0, const int cost = 0):weight(weight), cost(cost){    }
    49         boolean operator < (Milk another) const {
    50             return this->cost < another.cost;
    51         }
    52 }Milk;
    53 
    54 int n, m;
    55 Milk* milks;
    56 int result = 0;
    57 
    58 inline void init(){
    59     readInteger(n);
    60     readInteger(m);
    61     milks = new Milk[(const int)(m + 1)];
    62     for(int i = 1; i <= m; i++){
    63         readInteger(milks[i].cost);
    64         readInteger(milks[i].weight);
    65     }
    66 }
    67 
    68 inline void solve(){
    69     sort(milks + 1, milks + m + 1);
    70     for(int i = 1; i <= m && n; i++){
    71         int maxcer = min(n, milks[i].weight);
    72         result += maxcer * milks[i].cost;
    73         n -= maxcer;
    74     }
    75     printf("%d
    ", result);
    76 }
    77 
    78 int main(){
    79     freopen("milk.in", "r", stdin);
    80     freopen("milk.out", "w", stdout);
    81     init();
    82     solve();
    83     return 0;
    84 }
    Mixing Milk

    8.USACO 1.3 Barn Repair

    原题传送门[here]

    题目大意:

      用长度任意,数量不超过M的木板挡住有牛的牛棚(每个牛棚的长度都看作1, 一共有C个牛棚有牛,并且给出每只牛在哪个牛棚里)的出路(必须堵住所有牛棚的出口),求最小的木板的长度的和

    题解:

      首先把一段一段的连续有牛的牛棚之间的间隔的长度求出来,计算的方法是后一个的起始位置减去前一个的结束位置减1。只需要连接间隔较小的几段,所以就从小到大排序。需要连接的次数是 总空缺数减去M然后加1。接着把最小的几个加起来然后加上C就完成了。

     1 /*
     2 ID: m1582851
     3 PROG: barn1
     4 LANG: C++11
     5 */
     6 /**
     7  * USACO
     8  * Accepted
     9  * Time:0ms
    10  * Memory:4184k
    11  */
    12 #include<iostream>
    13 #include<cstdio>
    14 #include<cctype>
    15 #include<cstring>
    16 #include<cstdlib>
    17 #include<fstream>
    18 #include<sstream>
    19 #include<algorithm>
    20 #include<map>
    21 #include<set>
    22 #include<queue>
    23 #include<vector>
    24 #include<stack>
    25 using namespace std;
    26 typedef bool boolean;
    27 #define INF 0xfffffff
    28 #define smin(a, b) a = min(a, b)
    29 #define smax(a, b) a = max(a, b)
    30 template<typename T>
    31 inline void readInteger(T& u){
    32     char x;
    33     int aFlag = 1;
    34     while(!isdigit((x = getchar())) && x != '-');
    35     if(x == '-'){
    36         x = getchar();
    37         aFlag = -1;
    38     }
    39     for(u = x - '0'; isdigit((x = getchar())); u = (u << 1) + (u << 3) + x - '0');
    40     ungetc(x, stdin);
    41     u *= aFlag;
    42 }
    43 
    44 int m, s, c;
    45 vector<int> jgs;
    46 int* stalls;
    47 int result;
    48 
    49 inline void init(){
    50     readInteger(m);
    51     readInteger(s);
    52     readInteger(c);
    53     stalls = new int[(const int)(c + 1)];
    54     for(int i = 1; i <= c; i++){
    55         readInteger(stalls[i]);
    56     }
    57 }
    58 
    59 inline void solve(){
    60     sort(stalls + 1, stalls + c + 1);
    61     for(int i = 2; i <= c; i++){
    62         if(stalls[i] > stalls[i - 1] + 1)
    63             jgs.push_back(stalls[i] - stalls[i - 1] - 1);
    64     }
    65     sort(jgs.begin(), jgs.end());
    66     int needed = (signed)jgs.size() - m;
    67     result = c;
    68     for(int i = 0; i <= needed; i++){
    69         result += jgs[i];
    70     }
    71     printf("%d
    ", result);
    72 }
    73 
    74 int main(){
    75     freopen("barn1.in", "r", stdin);
    76     freopen("barn1.out", "w", stdout);
    77     init();
    78     solve();
    79     return 0;
    80 }
    Barn Repair
  • 相关阅读:
    Java 基础入门随笔(6) JavaSE版——数组操作
    Java 基础入门随笔(5) JavaSE版——函数重载
    Java 基础入门随笔(4) JavaSE版——程序流程控制
    Java 基础入门随笔(3) JavaSE版——逻辑运算符、位运算符
    jvm第二章(二)
    jvm第二章(一)
    jvm第一章(三)
    jvm第一章(二)
    jvm第一章(一)
    Java程序初始化的顺序是怎样的?
  • 原文地址:https://www.cnblogs.com/yyf0309/p/6071526.html
Copyright © 2020-2023  润新知