2020—1—29赛

dp问题
题目描述
小明的花店新开张,为了吸引顾客,他想在花店的门口摆上一排花,共m盆。通过调查顾客的喜好,小明列出了顾客最喜欢的n种花,从1到n标号。为了在门口展出更多种花,规定第i种花不能超过ai盆,摆花时同一种花放在一起,且不同种类的花需按标号的从小到大的顺序依次摆列。试编程计算,一共有多少种不同的摆花方案。 输入 第一行包含两个正整数n和m,中间用一个空格隔开。第二行有n个整数,每两个整数之间用一个空格隔开,依次表示a1、a2、……an。 0<n≤100,0<m≤100,0≤ ai≤100输出 输出只有一行,一个整数,表示有多少种方案。注意:因为方案数可能很多,请输出方案数对1000007取模的结果。
样例输入 Copy 2 43 2
样例输出 Copy 2

#include<bits/stdc++.h>
using namespace std;
int a[105];
int dp[105][105];

int main()
{
  int n,m;
  scanf("%d %d",&n,&m);
  dp[0][0]=1;
  for(int i=1;i<=n;i++)
  {
      scanf("%d",&a[i]);
      dp[i][0]=1;//每种花都可以
  }
  for(int i=1;i<=n;i++)//种类
  {
    for(int j=1;j<=m;j++)//数量
    {
        for(int k=j;k>=max(0,j-a[i]);k--)//很巧
        {
            dp[i][j]=(dp[i][j]+dp[i-1][k])%1000007;
        }
    }
  }
  printf("%d",dp[n][m]);
    return 0;
}

模拟,递归
题目描述
Snuke, who loves animals, built a zoo.
There are N animals in this zoo. They are conveniently numbered 1 through N, and arranged in a circle. The animal numbered i(2≤i≤N−1) is adjacent to the animals numbered i−1 and i+1. Also, the animal numbered 1 is adjacent to the animals numbered 2 and N, and the animal numbered N is adjacent to the animals numbered N−1 and 1.
There are two kinds of animals in this zoo: honest sheep that only speak the truth, and lying wolves that only tell lies.
Snuke cannot tell the difference between these two species, and asked each animal the following question: “Are your neighbors of the same species?” The animal numbered i answered si. Here, if si is o, the animal said that the two neighboring animals are of the same species, and if si is x, the animal said that the two neighboring animals are of different species.
More formally, a sheep answered o if the two neighboring animals are both sheep or both wolves, and answered x otherwise. Similarly, a wolf answered x if the two neighboring animals are both sheep or both wolves, and answered o otherwise.
Snuke is wondering whether there is a valid assignment of species to the animals that is consistent with these responses. If there is such an assignment, show one such assignment. Otherwise, print -1.

Constraints
3≤N≤105
s is a string of length N consisting of o and x.
输入
The input is given from Standard Input in the following format:
N
s
输出
If there does not exist an valid assignment that is consistent with s, print -1. Otherwise, print an string t in the following format. The output is considered correct if the assignment described by t is consistent with s.
·t is a string of length N consisting of S and W.
·If ti is S, it indicates that the animal numbered i is a sheep. If ti is W, it indicates that the animal numbered i is a wolf.

样例输入 Copy
6
ooxoox
样例输出 Copy
SSSWWS
提示
For example, if the animals numbered 1, 2, 3, 4, 5 and 6 are respectively a sheep, sheep, sheep, wolf, wolf, and sheep, it is consistent with their responses. Besides, there is another valid assignment of species: a wolf, sheep, wolf, sheep, wolf and wolf.
Let us remind you: if the neiboring animals are of the same species, a sheep answers o and a wolf answers x. If the neiboring animals are of different species, a sheep answers x and a wolf answers o.

题意理解:羊说真话,狼说假话,如果羊的左右是一样的,则为o,反之,如果是狼,则为x,于是借鉴博客,这种可以模拟这个过程,对于最开始两个动物,为羊羊\羊狼\狼羊\狼狼,于是我们就假设这四种情况,然后,再递推出其他位置,再检查

#include<bits/stdc++.h>
using namespace std;
int n;
int a[100005];
char str[100005];
void fun()
{
    for(int i=2;i<n;i++)
    {
        if(a[i-1]==1)
        {
            if(str[i-1]=='o') a[i]=a[i-2];
            if(str[i-1]=='x')
            {
                if(a[i-2]==1) a[i]=2;
                else a[i]=1;
            }
        }
        else if(a[i-1]==2)
        {
            if(str[i-1]=='x') a[i]=a[i-2];
            if(str[i-1]=='o')
            {
                if(a[i-2]==1) a[i]=2;
                else a[i]=1;
            }
        }
    }
}
int check()
{
    int r,l;
    char ch;
   for(int i=1;i<n;i++)
   {
       l=i-1;
       r=i+1;
       if(l<0) l=n-1;
       if(r>=n) r=0;
       if(a[i]==1)
       {
           if(a[l]==a[r]) ch='o';
           else ch='x';
       }
       else  if(a[i]==2)
       {
           if(a[l]==a[r]) ch='x';
           else ch='o';
       }
       if(ch!=str[i]) return 0;
   }
   return 1;

}
int main()
{
    scanf("%d",&n);
    scanf("%s",str);

    a[0]=1;a[1]=1;//全羊
    fun();
    if(check())
    {
        for(int i=0;i<n;i++)
        {
             if(a[i]==1) printf("S");
             else printf("W");
        }

      return 0;
    }
    a[0]=1;a[1]=2;
     fun();
    if(check())
    {
         for(int i=0;i<n;i++)
        {
             if(a[i]==1) printf("S");
             else printf("W");
        }
        return 0;
    }
    a[0]=2;a[1]=2;
     fun();
    if(check())
    {
         for(int i=0;i<n;i++)
        {
             if(a[i]==1) printf("S");
             else printf("W");
        }
        return 0;
    }
     a[0]=2;a[1]=1;
      fun();
    if(check())
    {
         for(int i=0;i<n;i++)
        {
             if(a[i]==1) printf("S");
             else printf("W");
        }
          return 0;
    }
        printf("-1");
          return 0;
}

排序优化,思维,构造
问题 I: Frequency
时间限制: 1 Sec 内存限制: 128 MB[提交] [状态] 题目描述 Snuke loves constructing integer sequences.There are N piles of stones, numbered 1 through N. The pile numbered i consists of ai stones.Snuke will construct an integer sequence s of length Σai, as follows:Among the piles with the largest number of stones remaining, let x be the index of the pile with the smallest index. Append x to the end of s.Select a pile with one or more stones remaining, and remove a stone from that pile.If there is a pile with one or more stones remaining, go back to step 1. Otherwise, terminate the process.We are interested in the lexicographically smallest sequence that can be constructed. For each of the integers 1,2,3,…,N, how many times does it occur in the lexicographically smallest sequence?Constraints1≤N≤1051≤ai≤109输入 The input is given from Standard Input in the following format:Na1 a2 … aN
输出 Print N lines. The i-th line should contain the number of the occurrences of the integer i in the lexicographically smallest sequence that can be constructed.
样例输入 Copy
2
1 2
样例输出 Copy
2
1
提示 The lexicographically smallest sequence is constructed as follows:Since the pile with the largest number of stones remaining is pile 2, append 2 to the end of s. Then, remove a stone from pile 2.Since the piles with the largest number of stones remaining are pile 1 and 2, append 1 to the end of s (we take the smallest index). Then, remove a stone from pile 2.Since the pile with the largest number of stones remaining is pile 1, append 1 to the end of s. Then, remove a stone from pile 1.The resulting sequence is (2,1,1). In this sequence, 1 occurs twice, and 2 occurs once.

  1. 题目大意:n个数,排序大的在前,若相同,则下标小的在前,所以bool cmp。将最大的所有数中,下标最小的那个取下来接在最小字典序(这句是废话 ),然后把最大的所有数中的下标最大的那个数减1。直到全为0停止
  2. 暴力法思路:用struct和order[ ]来表示下标和对应的值都可以,sort一次,做一次变化,当然是不行的,早炸了,而且数据量那么大
  3. 优化 :
    输入:2 2 2 1 1(下标为1 2 4 3 5)ans[1]++;
    第一次变化:2 2 1 1 1(1 2 3 4 5) ans[1]++;
    第二次变化:2 1 1 1 1 (1 2 3 4 5) ans[1]++;
    第三次变化:1 1 1 1 1(1 2 3 4 5)ans[1]+5;
    第四次变化:0 0 0 0 0(1 2 3 4 5)
    依次把最大(2)变为次大(1)
    而对应的frequency只有最大的;然后再把此时的最大(上次的次大)变为次大(上次的第三大)

第一次代码:暴力法 没过

#include<bits/stdc++.h>
using namespace std;
#define ll long long
ll int n;
ll int A[100005],order[100005],frequency[100005];
bool cmp(int x,int y)
{
    if(A[x]==A[y]) return x<y;
    return A[x]>A[y];

}
int main()
{
    scanf("%lld",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&A[i]);
        order[i]=i;
    }
    while(1)
    {
        sort(order+1,order+1+n,cmp);

        if(A[order[1]]==0) break;
        if(A[order[1]]-A[order[2]])
        {
            frequency[order[1]]+=(A[order[1]]-A[order[2]]);
            A[order[1]]=A[order[2]];
        }
        else
        {
            int k=1,po=1;
            for(;k<=n;k++)
            {
                if(A[order[k]]==A[order[1]])
                {
                    po=k;
                }
            }
            frequency[order[1]]++;
            A[order[po]]--;
        }

    }
   for(int i=1;i<=n;i++) printf("%lld\n",frequency[i]);

          return 0;
}

借鉴别人的优化后

#include<bits/stdc++.h>
using namespace std;
#define ll long long
ll int n;
ll int A[100005],order[100005],frequency[100005];
bool cmp(int x,int y)
{
    if(A[x]==A[y]) return x<y;
    return A[x]>A[y];

}
int main()
{
    scanf("%lld",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&A[i]);
        order[i]=i;
    }
     sort(order+1,order+1+n,cmp);
     A[order[n+1]]=0;
     int po=order[1];
     int temp=1;
    for(int i=2;i<=n+1;i++)
    {
        if( A[order[i]]==A[order[i-1]] ) temp++;
        else //(A[order[i]]<A[order[i-1]])
        {
            frequency[po]+=( temp * ( A[ order[i-1] ]-A[ order[i] ] ) );
            temp++;
        }
         if(order[i]<po)//只需要保证order 最小值为po
            {
               po=order[i];
            }
    }
   for(int i=1;i<=n;i++) printf("%lld\n",frequency[i]);

          return 0;
}

发布了32 篇原创文章 · 获赞 1 · 访问量 1356

猜你喜欢

转载自blog.csdn.net/QXK_Jack/article/details/104110968