7/26 CSU-ACM2018暑期训练3-递归&递推

题目链接

把M个同样的苹果放在N个同样的盘子里,允许有的盘子空着不放,问共有多少种不同的分法?(用K表示)5,1,1和1,5,1 是同一种分法。
Input
第一行是测试数据的数目t(0 <= t <= 20)。以下每行均包含二个整数M和N,以空格分开。1<=M,N<=10。
Output
对输入的每组数据M和N,用一行输出相应的K。
Sample Input
1
7 3
Sample Output
8

   分析:
        设f(m,n) 为m个苹果,n个盘子的放法数目,则先对n作讨论,
        当n>m:必定有n-m个盘子永远空着,去掉它们对摆放苹果方法数目不产生影响。即if(n>m) f(m,n) = f(m,m)  
        当n<=m:不同的放法可以分成两类:
        1、有至少一个盘子空着,即相当于f(m,n) = f(m,n-1);  
        2、所有盘子都有苹果,相当于可以从每个盘子中拿掉一个苹果,不影响不同放法的数目,即f(m,n) = f(m-n,n).
        而总的放苹果的放法数目等于两者的和,即 f(m,n) =f(m,n-1)+f(m-n,n) 
    递归出口条件说明:
        当n=1时,所有苹果都必须放在一个盘子里,所以返回1;
        当没有苹果可放时,定义为1种放法;
        递归的两条路,第一条n会逐渐减少,终会到达出口n==1; 
        第二条m会逐渐减少,因为n>m时,我们会return f(m,m) 所以终会到达出口m==0.
#include<cstdio>
#include<string>
#include<cstdlib>
#include<cmath>
#include<iostream>
#include<cstring>
#include<set>
#include<queue>
#include<algorithm>
#include<vector>
#include<map>
#include<cctype>
#include<stack>
#include<sstream>
#include<list>
#include<assert.h>
#include<bitset>
#include<numeric>
#define debug() puts("++++")
#define gcd(a,b) __gcd(a,b)
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define fi first
#define se second
#define pb push_back
#define sqr(x) ((x)*(x))
#define ms(a,b) memset(a,b,sizeof(a))
#define sz size()
#define be begin()
#define pu push_up
#define pd push_down
#define cl clear()
#define lowbit(x) -x&x
#define all 1,n,1
#define rep(i,x,n) for(int i=(x); i<(n); i++)
#define in freopen("in.in","r",stdin)
#define out freopen("out.out","w",stdout)
using namespace std;
typedef long long ll;
typedef unsigned long long ULL;
typedef pair<int,int> P;
const int INF = 0x3f3f3f3f;
const ll LNF = 1e18;
const int maxn = 1e3 + 20;
const int maxm = 1e6 + 10;
const double PI = acos(-1.0);
const double eps = 1e-8;
const int dx[] = {-1,1,0,0,1,1,-1,-1};
const int dy[] = {0,0,1,-1,1,-1,1,-1};
int dir[4][2] = {{0,1},{0,-1},{-1,0},{1,0}};
const int mon[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
const int monn[] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
ll n,m;
double a[150];
ll f(ll n,ll m) //n个苹果 m个盘子
{
    if(n==0 || m==1) return 1;
    else
    {
        if(m>n) return f(n,n);
        else return f(n,m-1)+f(n-m,m);
    }
}
int main()
{
    int T;
    cin>>T;
    while(T--)
    {
        cin>>n>>m;
        cout<<f(n,m)<<endl;
    }
}

Disky and Sooma, two of the biggest mega minds of Bangladesh went to a far country. They ate, coded
and wandered around, even in their holidays. They passed several months in this way. But everything
has an end. A holy person, Munsiji came into their life. Munsiji took them to derby (horse racing).
Munsiji enjoyed the race, but as usual Disky and Sooma did their as usual task instead of passing some
romantic moments. They were thinking- in how many ways a race can finish! Who knows, maybe this
is their romance!
In a race there are n horses. You have to output the number of ways the race can finish. Note that,
more than one horse may get the same position. For example, 2 horses can finish in 3 ways.

  1. Both first
  2. horse1 first and horse2 second
  3. horse2 first and horse1 second
    Input
    Input starts with an integer T (≤ 1000), denoting the number of test cases. Each case starts with a
    line containing an integer n (1 ≤ n ≤ 1000).
    Output
    For each case, print the case number and the number of ways the race can finish. The result can be
    very large, print the result modulo 10056.
    Sample Input
    3
    1
    2
    3
    Sample Output
    Case 1: 1
    Case 2: 3
    Case 3: 13
    【题意】:给定n匹马,要求出可能的排名情况(可能并列)
    【分析】:组合数学+DP;
    假设n个人比赛时的名次种数为dp[n],假设第一名有i个,则有C(n,i)种可能——从n匹马选任意i个并列第一,接下来有dp[ n - i ]种可能性,运用乘法原理求组和;所以dp[ n ] += C[n,i] * dp[ n - i ] (注意!枚举i为1到n并且求和/加法原理)
递推公式:
f(n)= ∑ C(n,i)* f(n-i)  (1≤ i ≤n)
f(0)=1 
可以列出前几项,
n=1 f(1)=f(0) 
n=2 C(2,1)*f(1)+C(2,2)*f(0) 
n=3 C(3,1)*f(2)+C(3,2)*f(1)+C(3,3)*f(0) 
…… 依次类推

在一次游戏中使用了N个盘子时,他需要多少次移动才能把他们都移到第三个柱子上?很显然,在没有第四个柱子时,问题的解是2^N-1,但现在有了这个柱子的帮助,又该是多少呢?
Input
包含多组数据,每个数据一行,是盘子的数目N(1<=N<=64)。
Output
对于每组数据,输出一个数,到达目标需要的最少的移动数。
Sample Input
1
3
12
Sample Output
1
5
81
【四柱汉诺塔】:

【参考论文】:论文链接

#include<cstdio>
#include<string>
#include<cstdlib>
#include<cmath>
#include<iostream>
#include<cstring>
#include<set>
#include<queue>
#include<algorithm>
#include<vector>
#include<map>
#include<cctype>
#include<stack>
#include<sstream>
#include<list>
#include<numeric>
#define debug() puts("++++")
#define gcd(a,b) __gcd(a,b)
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define fi first
#define se second
#define pb push_back
#define sqr(x) ((x)*(x))
#define ms(a,b) memset(a,b,sizeof(a))
#define sz size()
#define be begin()
#define pu push_up
#define pd push_down
#define cl clear()
#define lowbit(x) -x&x
#define all 1,n,1
#define rep(i,x,n) for(int i=(x); i<(n); i++)
#define repe(i,x,n) for(int i=(x); i<=(n); i++)
#define in freopen("in.in","r",stdin)
#define out freopen("out.out","w",stdout)
using namespace std;
typedef long long ll;
typedef unsigned long long ULL;
typedef pair<int,int> P;
const int INF = 0x3f3f3f3f;
const int mod = 10056;
const ll LNF = 1e18;
const int maxn = 1e4;
const int maxm = 1e6 + 10;
const double PI = acos(-1.0);
const double eps = 1e-8;
const int dx[] = {-1,1,0,0,1,1,-1,-1};
const int dy[] = {0,0,1,-1,1,-1,1,-1};
int dir[4][2] = {{0,1},{0,-1},{-1,0},{1,0}};
const int mon[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
const int monn[] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};


int main()
{
    int a[100],i,n,j;
    a[1]=1;a[2]=3;
    for(i=3;i<65;i++)
    {
        int min=99999999;
        for(j=1;j<i;j++)
        {
            if(2*a[j]+pow(2.0,i-j)-1<min)
                min=2*a[j]+pow(2.0,i-j)-1;
        }
        a[i]=min;
    }
    while(~scanf("%d",&n))
    {
        printf("%d\n",a[n]);
    }
    return 0;
}

We will construct an infinitely long string from two short strings: A = "^^" (four characters), and B = "T.T" (three characters). Repeat the following steps:
Concatenate A after B to obtain a new string C. For example, if A = "^
^" and B = "T.T", then C = BA = "T.T^^".
Let A = B, B = C -- as the example above A = "T.T", B = "T.T^
^".
Your task is to find out the n-th character of this infinite string.

Input

The input contains multiple test cases, each contains only one integer N (1 <= N <= 2^63 - 1). Proceed to the end of file.

Output

For each test case, print one character on each line, which is the N-th (index begins with 1) character of this infinite string.

Sample Input

1
2
4
8

Sample Output

T
.
^
T

#include<cstdio>
#include<string>
#include<cstdlib>
#include<cmath>
#include<iostream>
#include<cstring>
#include<set>
#include<queue>
#include<algorithm>
#include<vector>
#include<map>
#include<cctype>
#include<stack>
#include<sstream>
#include<list>
#include<numeric>
#define debug() puts("++++")
#define gcd(a,b) __gcd(a,b)
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define fi first
#define se second
#define pb push_back
#define sqr(x) ((x)*(x))
#define ms(a,b) memset(a,b,sizeof(a))
#define sz size()
#define be begin()
#define pu push_up
#define pd push_down
#define cl clear()
#define lowbit(x) -x&x
#define all 1,n,1
#define rep(i,x,n) for(int i=(x); i<(n); i++)
#define in freopen("in.in","r",stdin)
#define out freopen("out.out","w",stdout)
using namespace std;
typedef long long ll;
typedef unsigned long long ULL;
typedef pair<int,int> P;
const int INF = 0x3f3f3f3f;
const ll LNF = 1e18;
const int maxn = 90;
const int maxm = 1e6 + 10;
const double PI = acos(-1.0);
const double eps = 1e-8;
const int dx[] = {-1,1,0,0,1,1,-1,-1};
const int dy[] = {0,0,1,-1,1,-1,1,-1};
int dir[4][2] = {{0,1},{0,-1},{-1,0},{1,0}};
const int mon[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
const int monn[] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
ll n,m;
ll a[maxn+5];
char *s="T.T^__^";
void init()
{
    a[0]=4;
    a[1]=3;
    for(ll i=2;i<maxn;i++)
    {
        a[i] = a[i-1] + a[i-2];
    }
}
int main()
{
    init();
    while(~scanf("%lld",&n))
    {

        while(n>7)
        {
            ll pos = lower_bound(a,a+maxn,n)-a;
            n -= a[pos-1];
        }
        printf("%c\n",s[n-1]);
    }
}

猜你喜欢

转载自www.cnblogs.com/Roni-i/p/9371739.html
今日推荐