1.间隔取最大数(dp)E. Pavel and Triangles(思维) 每日两刷2019/4/15

链接:https://ac.nowcoder.com/acm/contest/558/I
来源:牛客网

题目描述
小猫在研究序列。小猫在研究选择。
给定一个长度为N的序列a1,a2,…,aN,请你在这N个元素中选出一些(可以不选,可以全选),使得对于任意1≤i<N,ai与ai+1不被同时选,求选出的数的和最大是多少。

输入描述:

第一行一个正整数T,表示数据组数。每组数据的第一行一个正整数N。接下来一行N个正整数a1,a2,…,aN。

输出描述:

T行,每行一个整数,表示每组数据的答案。

示例1
输入

3
5
1 100 101 100 1
4
1 2 3 4
3
51 100 51

输出

200
6
102

备注:

1≤T,N,ai≤100

题目思路:

同学问我的一道题,很裸的dp。
建立一个dp[ i ][ j ] //i为到第i个数,j=0则表示取这个数,j=1则表示不取这个数
所以状态转移方程为:
if(j==1) //取第i个数的时候
if(dp [ i ][ j ]<dp [ i-1 ][ 0 ]+a [ i ])
dp [ i ][ j ]=dp [ i-1 ][ 0 ]+a [ i ];

if(j==0) //不取第i个数的时候
dp [ i ][ j ]=max(dp [ i-1 ][ 0 ] ,dp [ i-1 ][ 1 ]);

#include <bits/stdc++.h>
#define ll long long
using namespace std;

ll dp[105][3];
ll a[105];
int main(){
    int T;
    scanf("%d",&T);
    while(T--){
        memset(dp,0,sizeof(dp));
        memset(a,0,sizeof(a));
        int n;
        scanf("%d",&n);
        for(int i=1;i<=n;i++){
            scanf("%lld",&a[i]);
        }
        dp[0][0]=0;
        dp[0][1]=0;
        for(int i=1;i<=n;i++){
            for(int j=0;j<=1;j++){
              if(j==1){
                if(dp[i][j]<dp[i-1][0]+a[i])
                   dp[i][j]=dp[i-1][0]+a[i];
              }
              if(j==0){
                dp[i][j]=max(dp[i-1][0],dp[i-1][1]);
              }
            }
        }
     cout<<max(dp[n][0],dp[n][1])<<endl; //最后一个数可能取,可能不取
  }
}

E. Pavel and Triangles

time limit per test 2 seconds
memory limit per test 256 megabytes
inputstandard input
outputstandard output
Pavel has several sticks with lengths equal to powers of two.
He has a0 sticks of length 20=1, a1 sticks of length 21=2, …, an−1 sticks of length 2n−1.
Pavel wants to make the maximum possible number of triangles using these sticks. The triangles should have strictly positive area, each stick can be used in at most one triangle.
It is forbidden to break sticks, and each triangle should consist of exactly three sticks.
Find the maximum possible number of triangles.

Input

The first line contains a single integer n (1≤n≤300000) — the number of different lengths of sticks.
The second line contains n integers a0, a1, …, an−1 (1≤ai≤109), where ai is the number of sticks with the length equal to 2i.

Output

Print a single integer — the maximum possible number of non-degenerate triangles that Pavel can make.

Examples
input

5
1 2 2 2 2

output

3

input

3
1 1 1

output

0

input

3
3 3 3

output

3

Note

In the first example, Pavel can, for example, make this set of triangles (the lengths of the sides of the triangles are listed): (20,24,24), (21,23,23), (21,22,22).
In the second example, Pavel cannot make a single triangle.
In the third example, Pavel can, for example, create this set of triangles (the lengths of the sides of the triangles are listed): (20,20,20), (21,21,21), (22,22,22).

题目大意:

给你不同长度的木棍的长度(21,22,23,),还有个数,求最多更构造多少个三角形。

题目思路:

不可能存在连续三个(如21,22,23)构成三角形,所以一定是由三个相同的或者两个相同的一个不同的构成的三角形。
所以在存入数量时,一个是所有的本身除于三的情况,还有一个是本身除于二

#include <bits/stdc++.h>
using namespace std;

int main(){
    long long n,a,ans=0,b=0;
    cin>>n;
    for(int i=1; i<=n; i+=1){
        cin>>a;
        b+=a;
        ans=min(b/3, ans + a/2);
    }
    cout<<ans;
}

下面这个比较好理解。

#include <bits/stdc++.h>
using namespace std;

long long n, t, ans, a, tmp;

int main(){
	scanf("%lld", &n);
	while (n--){
		scanf("%lld", &a);
		ans+=(tmp=min(t, a/2)); //选两个相同和一个不同的时候
		t-=tmp;
		ans+=(a-=2*tmp)/3;  //选三个相同的时候
		t+=a%3;
	}
	printf("%lld\n", ans);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_43333395/article/details/89322472