糖果


题目描述
你有 nm 颗糖果。如果有 n 个小朋友来你家,你需要分给他们每人 m 颗糖;如果来的是
m 个小朋友,你就要分给每人 n 颗。
你打算把糖果分装在 k 个盒子里,每个盒子分别放几颗糖由你来决定。分糖果时,盒子是
不能被拆开的。(小朋友们拿到的只能是装着糖果的盒子,而不是散装的糖果)
你希望最小化盒子的数量 k,使得不论来了 n 个还是 m 个小朋友,你都能按照要求给他
们分糖果。
输入格式
第一行包含三个整数 n, m, t。
输出格式
如果 t = 0,你只需输出一个整数,表示最小的 k。
如果 t = 1,你需要在第一行输出一个整数,表示最小的 k;在第二行输出由空格隔开的 k
个整数,按照降序排列,表示每个盒子内的糖果数量。如果有多种方案使得 k 最小,你需要输
出其中字典序最大的。
样例输入 1
3 4 0
样例输出 1
6
样例输入 2
3 4 1
样例输出 2
6
3 3 3 1 1 1
样例解释
如 果 来 了 3 个 小 朋 友, 分 别 给 {3, 1}, {3, 1}, {3, 1}; 如 果 来 了 4 个 小 朋 友, 分 别 给
{3}, {3}, {3}, {1, 1, 1}。
另外,{3, 3, 2, 2, 1, 1} 也是一组使得 k 最小的合法解,但它并不是字典序最大的。

 

题解:

  这个题目,代码十分短,但在考试时候没有发现,当然,考试的时候,想发现构造题和贪心题还有dp题,手玩都特别有好处,所以想不出来还是要手玩一下。

  题目本身就是一个更相减损法,递归子问题。

代码:

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <iostream>
#define MAXN 100
using namespace std;
int ans;

void dfs2(int n,int m,int num){
    if(n==m) {num+=n;ans=num;return;}
    else{
        num+=m;
        n-=m;
        if(n<m) swap(n,m);
        dfs2(n,m,num);
    }
}

void dfs1(int n,int m){
    if(n==m){
        for(int i=1;i<=n;i++) printf("%d ",n);
        return;
    }
    else{
        for(int i=1;i<=m;i++) printf("%d ",m);
        n-=m;
        if(n<m) swap(n,m);
        dfs1(n,m);
    }
}

int main()
{
    int t,n,m;
    scanf("%d%d%d",&n,&m,&t);
    if(n<m) swap(n,m);
    dfs2(n,m,0);
    printf("%d\n",ans);
    if(t==1) dfs1(n,m);
    return 0;
}

 

posted @ 2017-09-14 18:45  人间失格—太宰治  阅读(334)  评论(0编辑  收藏  举报