DP习题集

DP

不同路径的最值合成目标值:

描述:给定一个target,找到大(小)的 cost/path/sum 来达到这个target。

方法

dp[i] = min(dp[i - 1], dp[i - 2], ... , dp[i - k]) + cost[i];
 ways 代表了到达dp[i]状态的方案数
 
for (int i = 1; i <= target; ++i) {
    
     // i 不是索引,而是 目标值
	for (int j = 0; j < ways.size; ++j) {
    
    
	 	if (ways[j] <= i) {
    
    
	 		dp[i] = min(dp[i], dp[i - ways[j]]) + cost / path / sum;
	 	}
	}
}
return dp[target];

示例:

最小路径和

for (int i = 1; i < n; ++i) {
    
    
	for (int j = 1; j < m; ++j) {
    
    
		grid[i][j] = min(grid[i - 1][j], grid[i][j - 1]) + grid[i][j];
	}
}
return grid[n - 1][m - 1];

达到目标的不同方式的个数

给一个目标,问到达目标的不同方式的个数,一般会给出target,让你求合成它的方法数

方法:

dp[i] = dp[i - 1] + dp[i - 2] , ... , + dp[i - k];

比如
    走台阶: k=2  dp[i] = dp[i - 1] + dp[i - 2]

例题:

爬楼梯

for (int i = 2; i <= n; ++i) 
	dp[i] = dp[i - 1] + dp[i - 2] ;
	

区间合并

给定一组数字,考虑当前 i 以及从左侧和右侧可获得的最佳值,找到问题的最佳解决方案,类似 Last Year’s Substring

方法:

dp[i][j]=dp[i][k]+dp[k+1][j]+sum[i][j];

例题:石子归并:

描述 有N堆石子排成一排,每堆石子有一定的数量。现要将N堆石子并成为一堆。合并的过程只能每次将相邻的两堆石子堆成一堆,并将新的一堆石子数记为该次合并的得分。

给组测试数据

输入   4    表示有4堆石子

4 4 5 9  表示每堆石子的个数

输出 54 表示最大的得分

分析:

dp[1].[1]=4;dp[2].[2]=4;dp[3].[3]=5;dp[4].[4]=9。
然后我在长度为2的时候记录,dp[1].[2]=4+4=8,dp[2].[3]=8+5=13;dp[3].[4]=13+9=22;这样加起来的值就是8+14+22=44;
但是如果我反过来呢?dp[1].[2]=5+9=14;dp[2].[3]=14+4=18;dp[3].[4]=18+4=22;这样加起来的值就是14+18+22=54。很明显,54就是所求的最大值。
具体来说我们应该定义一个数组dp[i,j]用来表示合并方法,i表示从编号为i的石头开始合并,j表示所求区间的结尾,sum表示的是石头的数量。

对于上面的例子来说

第一阶段:dp[1].[1],dp[2].[2],dp[3].[3],dp[4].[4] 因为一开始还没有合并,所以这些值应该全部为0。

第二阶段:两两合并过程如下,其中sum(i,j)表示石头的数量,即从i开始数j个数的和

		dp[1,2]=dp[1,1]+dp[2,2]+sum[1,2];

     dp[2,3]=dp[2,2]+dp[3,3]+sum[2,3];

     dp[3,4]=dp[3,3]+dp[4,4]+sum[4,4];

第三阶段:三三合并可以拆成两两合并,拆分方法有两种,前两个为一组或后两个为一组

		dp[1,3]=dp[1,2]+dp[3,3]+sum[1,3]或dp[1,3]=dp[1,1]+dp[2,3]+sum[1,3];取其最优

      dp[2,4]=dp[2,2]+dp[3,4]+sun[2,4]或dp[2,4]=dp[2,3]+dp[3,3]+sum[2,4];取其最优

第四阶段:四四合并的拆分方法用三种,同理求出三种分法的得分,取其最优即可

  动态方程为dp[i][j]=dp[i][k]+dp[k+1][j]+sum[i][j];
	dp[i][j]=min(dp[i][j],dp[i][k]+dp[k+1][j]+sum[i][j]) 

字符串问题

此情况下不同的题的问题陈述差别挺大,但大多数情况下,题目会给两个字符串,这些字符串的长度并不大

最长公共字串

for (int i = 1; i <= n; ++i) {
    
    
	for (int j = 1; j <= m; ++j) {
    
    
		if (a[i - 1] == a[j - 1]) //相同
			dp[i][j] = dp[i - 1][j - 1] + 1;
		else//不同
			dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);
	}
}

最长上升子序列:Maximum Increase

#include<iostream> 
using namespace std;
int main()
{
    
    
		int maxx=1;
		int n;
		cin>>n;
		int dp[100001],a[100001];
		for(int i=0;i<n;i++)cin>>a[i],dp[i]=1;
		for(int i=1;i<n;i++)
			if(a[i]>a[i-1])
			{
    
    
				dp[i]=dp[i-1]+1;
				maxx=max(maxx,dp[i]);
			}
			
			cout<<maxx<<endl;
}

背包问题

01 背包问题

N 件物品和一个容量为 V 的背包。放入第 i 件物品耗费的费用是 C1,得到的价值是 Wi。求解将哪些物品装入背包可使价值总和最大。

F[i, v] = max{F[i-1, v], F[i-1, v-Ci]+Wi}
int f[100];
int v[15];
int t[15];
int main(){
    
    
	int n,m;
	cin>>n>>m;//体积为n,物品种类为m
	for(int i=1;i<=m;i++)
	{
    
    
	cin>>t[i]>>v[i];
	}//输入量和体积
	for(int i=1;i<=m;i++)
	{
    
    
		for(int j=n;j>=t[i];j--)
		{
    
    
		f[i]=max(f[j],f[j-t[i]]+v[i]);//动态转移
		}
	}
	cout<<f[n]<<endl;
}

完全背包问题

有 N 种物品和一个容量为 V 的背包,每种物品都有无限件可用。放入第 i 种物品的费用是 Ci,价值是 Wi。求解:将哪些物品装入背包,可使这些物品的耗费的费用总和不超过背包容量,且价值总和最大。

这个问题非常类似于 01 背包问题,所不同的是每种物品有无限件。也就是从每种物品的角度考虑,与它相关的策略已并非取或不取两种,而是有取 0 件、取 1 件、取 2件……直至取 ⌊V /Ci⌋ 件等许多种。

如果仍然按照解 01 背包时的思路,令 F[i, v] 表示前 i 种物品恰放入一个容量为 v

的背包的最大权值。仍然可以按照每种物品不同的策略写出状态转移方程,像这样:

F[i, v] = max{F[i-1, v-kCi] + kWi | 0 ≤ kCi ≤ v}
int T,m;
int W[MAXM][100005];
int t[MAXM],w[MAXM];
int main(){
    
    
	cin>>T>>m;//输入总空间T,和物品种类
	for(int i=1;i<=m;i++){
    
    
	      cin>>t[i]>>w[i];//输入价值和体积
	}
	 for(int i=1;i<=m;i++){
    
    
	       for(int j=0;j<=T;j++){
    
    
	             for(int k=1;k*t[i]<=j;k++){
    
    
		 W[i][j]=max(W[i][j],W[i-1][j-k*t[i]]+k*w[i]);
		}
	    }
	  }
	cout<<W[m][T]<<endl;
	return 0;
}

DP题解

Hit the Lottery

题意:

Allen has a LOT of money. He has n dollars in the bank. For security reasons, he wants to withdraw it in cash (we will not disclose the reasons here). The denominations for dollar bills are 1, 5, 10, 20, 100. What is the minimum number of bills Allen could receive after withdrawing his entire balance?

Input

The first and only line of input contains a single integer n (1≤n≤109).

Output

Output the minimum number of bills that Allen could receive.

Example

Input

125

Output

3

Input

43

Output

5

Input

1000000000

Output

10000000

Note

In the first sample case, Allen can withdraw this with a 100 dollar bill, a 20 dollar bill, and a 5 dollar bill. There is no way for Allen to receive 125 dollars in one or two bills.

In the second sample case, Allen can withdraw two 20 dollar bills and three 1 dollar bills.

In the third sample case, Allen can withdraw 100000000 (ten million!) 100 dollar bills.

题意

  • k1+k2×5+k3×10+k4×20+k5×100=n
  • 求 k*1+k2+k3+k4+k5 的最小值。

解决

让k5尽可能大,k4其次,以此类推。

即:k5尽量被100整出,k4尽量被20整除。

Code:

#include<iostream> 
using namespace std;
int main()
{
    
    
	int dp[5]={
    
    1,5,10,20,100};//定义面值
	int ans;//总面值
	int num=0;
	cin>>ans;
	for(int i=4;i>=0;i--)
	{
    
    
		num+=ans/dp[i];//从大到小进行,先从100再到20再到10再到5最后到1
		ans%=dp[i];
	}
	cout<<num;
}

Maximum Increase

题目描述

You are given array consisting of n integers. Your task is to find the maximum length of an increasing subarray of the given array.

A subarray is the sequence of consecutive elements of the array. Subarray is called increasing if each element of this subarray strictly greater than previous.

Input

The first line contains single positive integer n (1 ≤ n ≤ 105) — the number of integers.

The second line contains n positive integers a1, a2, …, a**n (1 ≤ a**i ≤ 109).

Output

Print the maximum length of an increasing subarray of the given array.

Examples

Input

5
1 7 2 11 15

Output

3

Input

6
100 100 100 100 100 100

Output

1

Input

3
1 2 3

Output

3

题意

找出最大增长的序列长度

解决:

状态转移方程如下:

如果a[i]>a[i-1]则:dp[i]=dp[i-1]+1。

并且把最大值始终赋给maxx

否则不进行转移。

注意: 其中s[]数组要赋值为1,因为本身就是一个上升的字。

Code

#include<iostream> 
using namespace std;
int main()
{
    
    
		int maxx=1;
		int n;
		cin>>n;
		int dp[100001],a[100001];
		for(int i=0;i<n;i++)cin>>a[i],dp[i]=1;
		for(int i=1;i<n;i++)
			if(a[i]>a[i-1])
			{
    
    
				dp[i]=dp[i-1]+1;
				maxx=max(maxx,dp[i]);
			}
			
			cout<<maxx<<endl;
}

Fair Division

题目描述

Alice and Bob received ncandies from their parents. Each candy weighs either 1 gram or 2 grams. Now they want to divide all candies among themselves fairly so that the total weight of Alice’s candies is equal to the total weight of Bob’s candies.

Check if they can do that.

Note that candies are not allowed to be cut in half.

Input

The first line contains one integer t (1≤t≤1041≤t≤104) — the number of test cases. Then t test cases follow.

The first line of each test case contains an integer n (1≤n≤1001≤n≤100) — the number of candies that Alice and Bob received.

The next line contains n integers a1,a2,…,ana1,a2,…,an — the weights of the candies. The weight of each candy is either 1 or 2.

It is guaranteed that the sum of n over all test cases does not exceed 105.

Output

For each test case, output on a separate line:

  • “YES”, if all candies can be divided into two sets with the same weight;
  • “NO” otherwise.

You can output “YES” and “NO” in any case (for example, the strings yes, Yes and YES will be recognized as positive).

Example

Input

5
2
1 1
2
1 2
4
1 2 1 2
3
2 2 2
3
2 1 2

Output

YES
NO
YES
NO
NO

Note

In the first test case, Alice and Bob can each take one candy, then both will have a total weight of 1.

In the second test case, any division will be unfair.

In the third test case, both Alice and Bob can take two candies, one of weight 11 and one of weight 2.

In the fourth test case, it is impossible to divide three identical candies between two people.

In the fifth test case, any division will also be unfair.

题意:

两个人能不能得到相同的数量。有1,有2,最后两个人得到的1乘n1+2乘n2

简单来说就是n1+2×2=n3+2×n4且n1+n3等于1的总数,n2+n4等于2的总数

Code

#include<iostream> 
using namespace std;
int main()
{
    
    
	int T;
	cin>>T;
	while(T--)
	{
    
    
		int n;
		int n1,n2;
		n1=0;
		n2=0;
		cin>>n;
		int a;
		for(int i=1;i<=n;i++){
    
    //对1和2的数量进行统计。
			cin>>a;
			if(a==1)n1++;
				else n2++;
			}
		if((n1%2==0&&n1!=0)||(n1==0&&n2%2==0))cout<<"YES"<<endl;else cout<<"NO"<<endl;//是否满足均分
	}
}

QAQ

题目描述:

“QAQ” is a word to denote an expression of crying. Imagine “Q” as eyes with tears and “A” as a mouth.

Now Diamond has given Bort a string consisting of only uppercase English letters of length n. There is a great number of “QAQ” in the string (Diamond is so cute!).

Bort wants to know how many subsequences “QAQ” are in the string Diamond has given. Note that the letters “QAQ” don’t have to be consecutive, but the order of letters should be exact.

Input

The only line contains a string of length n (1 ≤ n ≤ 100). It’s guaranteed that the string only contains uppercase English letters.

Output

Print a single integer — the number of subsequences “QAQ” in the string.

Examples

Input

QAQAQYSYIOIWIN

Output

4

Input

QAQQQZZYNOIWIN

Output

3

Note

In the first example there are 4 subsequences “QAQ”: “QAQAQYSYIOIWIN”, “QAQAQYSYIOIWIN”, “QAQAQYSYIOIWIN”, “QAQAQYSYIOIWIN”.

题意

简单来说就是有多少QAQ的组合,第一个Q必须在A的前面,但不要求紧挨,第二个Q要求在A的后面也不要求紧挨

解决:

统计A前面的Q的数量,统计A后面的Q的数量,两者进行一一组合即相乘,即使用前缀和统计个数。

Code

#include<iostream> 
#include<string>
using namespace std;
int main()
{
    
    
	string s;
	cin>>s;
	int n=s.length();
	int res=0,maxx=0;
	int sum[101];
	for(int i=0;i<n;i++)
	{
    
    
		if(s[i]=='Q')res++;
		sum[i]=res;
	}
	for(int i=0;i<n;i++)
	{
    
    
		if(s[i]=='A')
			maxx+=(sum[n-1]-sum[i])*sum[i];
		//cout<<(sum[n-1]-sum[i])*sum[i];
			 
	}
	cout<<maxx;
}

Last Year’s Substring

题目描述

Polycarp has a string s[1…n]s[1…n] of length n consisting of decimal digits. Polycarp performs the following operation with the string ssno more than once (i.e. he can perform operation 00 or 11 time):

  • Polycarp selects two numbers i and j (1≤i≤j≤n) and removes characters from the s string at the positions i,i+1,i+2,…,jj (i.e. removes substring s[i…j]). More formally, Polycarp turns the string s into the string s1s2…si−1sj+1sj+2…sn.

For example, the string s=s=“20192020” Polycarp can turn into strings:

  • “2020” (in this case(i,j)=(3,6) or (i,j)=(1,4));
  • “2019220” (in this case(i,j)=(6,6));
  • “020” (in this case (i,j)=(1,5));
  • other operations are also possible, only a few of them are listed above.

Polycarp likes the string “2020” very much, so he is wondering if it is possible to turn the string s into a string “2020” in no more than one operation? Note that you can perform zero operations.

Input

The first line contains a positive integer tt (1≤t≤1000) — number of test cases in the test. Then t test cases follow.

The first line of each test case contains an integer n (4≤n≤200) — length of the string s. The next line contains a string s of length n consisting of decimal digits. It is allowed that the string s starts with digit 0.

Output

For each test case, output on a separate line:

  • “YES” if Polycarp can turn the string ss into a string “2020” in no more than one operation (i.e. he can perform 00 or 11 operation);
  • “NO” otherwise.

You may print every letter of “YES” and “NO” in any case you want (so, for example, the strings yEs, yes, Yes and YES will all be recognized as positive answer).

Example

Input

6
8
20192020
8
22019020
4
2020
5
20002
6
729040
6
200200

Output

YES
YES
YES
NO
NO
NO

Note

In the first test case, Polycarp could choose i=3and j=6.

In the second test case, Polycarp could choose i=2 and j=5.

In the third test case, Polycarp did not perform any operations with the string.

题意:

在字符串中连续删去一段,能否在数字串中找到“2020”组合。

题解:

2020只有四位,且删除的是连续的字段,故删去中间一段,或者留下前四位或者留下后四位。

删除中间一段

即留下第一位和后三位

留下前两位和后两位

留下前三位和最后一位

如果在这几中删除中不存在留下的为2020那么就输出NO否则输出yes

Code

#include<iostream> 
#include<string>
using namespace std;
int main()
{
    
    
	int T;
	int n;
	string s;
	cin>>T;
	while(T--)
	{
    
    
		cin>>n;cin>>s;
		int n=s.length();
		int flag=0;
		//截取的必须是连续的因此 截取中间的或者头尾的
		if(s[0]=='2'&&s[1]=='0'&&s[n-2]=='2'&&s[n-1]=='0'){
    
    
			flag=1;
		}
		if(s[0]=='2'&&s[1]=='0'&&s[2]=='2'&&s[3]=='0'){
    
    
			flag=1;
		}
		if(s[0]=='2'&&s[n-3]=='0'&&s[n-2]=='2'&&s[n-1]=='0'){
    
    
			flag=1;
		}
		if(s[n-4]=='2'&&s[n-3]=='0'&&s[n-2]=='2'&&s[n-1]=='0'){
    
    
			flag=1;
		}
		if(s[0]=='2'&&s[1]=='0'&&s[2]=='2'&&s[n-1]=='0'){
    
    
			flag=1;
		}
		if(flag==1)cout<<"YES"<<endl;
		else cout<<"NO"<<endl;
	}
}

Alex and a Rhombus

题目描述:

While playing with geometric figures Alex has accidentally invented a concept of a n-th order rhombus in a cell grid.

A 1-st order rhombus is just a square 1×11×1 (i.e just a cell).

A n-th order rhombus for all n≥2n≥2 one obtains from a n−1-th order rhombus adding all cells which have a common side with it to it (look at the picture to understand it better).

在这里插入图片描述

Alex asks you to compute the number of cells in a n-th order rhombus.

Input

The first and only input line contains integer n (1≤n≤100) — order of a rhombus whose numbers of cells should be computed.

Output

Print exactly one integer — the number of cells in a n-th order rhombus.

Examples

Input

1

Output

1

Input

2

Output

5

Input

3

Output

13

Note

Images of rhombus corresponding to the examples are given in the statement.

题意:

算格子数

题解:

第一个为1,第二个为5,第三个为13,第二个比第一个多4,第三个比第二个多8,以此类推dp[i]=dp[i-1]+4*(i-1).

Code

#include<iostream> 
#include<string>
using namespace std;
int main()
{
    
    

	int n;
	int sum=1;
	int dp[101];
	dp[1]=1;
	cin>>n;
	for(int i=2;i<=n;i++)
	{
    
    
		dp[i]=dp[i-1]+4*(i-1);
	}
	cout<<dp[n]<<endl;

}

Last minute enhancements

题目描述:

Athenaeus has just finished creating his latest musical composition and will present it tomorrow to the people of Athens. Unfortunately, the melody is rather dull and highly likely won’t be met with a warm reception.

His song consists of n notes, which we will treat as positive integers. The diversity of a song is the number of different notes it contains. As a patron of music, Euterpe watches over composers and guides them throughout the process of creating new melodies. She decided to help Athenaeus by changing his song to make it more diverse.

Being a minor goddess, she cannot arbitrarily change the song. Instead, for each of the nn notes in the song, she can either leave it as it is or increase it by 11.

Given the song as a sequence of integers describing the notes, find out the maximal, achievable diversity.

Input

The input consists of multiple test cases. The first line contains an integer t (1≤t≤10000) — the number of test cases. Then tt test cases follow, each one is described in two lines.

In the first line of each test case there is a single integer n (1≤n≤1051≤n≤105) denoting the length of the song. The next line contains a sequence of n integers x1,x2,…,xn (1≤x1≤x2≤…≤xn≤2⋅n), describing the song.

The sum of n over all test cases does not exceed 105105.

Output

For each test case, you should output a single line containing precisely one integer, the maximal diversity of the song, i.e. the maximal possible number of different elements in the final sequence.

Example

Input

5
6
1 2 2 2 5 6
2
4 4
6
1 1 3 4 4 5
1
1
6
1 1 1 2 2 2

Output

5
2
6
1
3

Note

In the first test case, Euterpe can increase the second, fifth and sixth element to obtain the sequence 1,3–,2,2,6–,7–1,3_,2,2,6_,7_, which has 55 different elements (increased elements are underlined).

In the second test case, Euterpe can increase the first element to obtain the sequence 5–,45_,4, which has 22 different elements.

In the third test case, Euterpe can increase the second, fifth and sixth element to obtain the sequence 1,2–,3,4,5–,6–1,2_,3,4,5_,6_, which has 66 different elements.

题意:

给你一个数组,有n个数字,对于每个数字,你可以使其不变或使其+1,怎样操作能使最后数组中不同的数字最多?

解决:

若出现过就设置为1,最后1的个数便是最优答案。

定义一个a数组存放输入的,定义一个b数组,然后b数组的值都设置为0,然后把a数组的值作为b数组的下标,如果此下标访问b数组时为0,那就说明此下标还没计算过,访问完了后记为1即访问过此数了,如果此数访问时为1,那就访问次数的+1,如此以来,就可以计算出有多少种最多。

Code

#include<iostream> 
#include<string.h>
#include<cstdio>
using namespace std;
	int T;
	int n;
	int sum;
	int a[100002];
	int b[200002];
int main()
{
    
    
	scanf("%d",&T);
	while(T--)
{
    
    
	sum=0;
	scanf("%d",&n);
	memset(b,0,sizeof(b));
	for(int i=1;i<=n;i++)
	{
    
    
		scanf("%d",&a[i]);
		if(b[a[i]]==0)
		{
    
    
			b[a[i]]=1;
			sum++;
		}
		else{
    
    
			if(b[a[i]+1]==0)
			{
    
    
				b[a[i]+1]=1;
				sum++;
			}
		}
	}
	cout<<sum<<endl;
}

}

Even Subset Sum Problem

题目描述

You are given an array aa consisting of n positive integers. Find a non-empty subset of its elements such that their sum is even (i.e. divisible by 22) or determine that there is no such subset.

Both the given array and required subset may contain equal values.

Input

The first line contains a single integer t (1≤t≤100), number of test cases to solve. Descriptions of t test cases follow.

A description of each test case consists of two lines. The first line contains a single integer n (1≤n≤1001≤n≤100), length of array aa.

The second line contains n integers a1,a2,…,ana1,a2,…,an (1≤ai≤100), elements of aa. The given array aa can contain equal values (duplicates).

Output

For each test case output −1−1 if there is no such subset of elements. Otherwise output positive integer kk, number of elements in the required subset. Then output kk distinct integers (1≤pi≤n1≤pi≤n), indexes of the chosen elements. If there are multiple solutions output any of them.

Example

Input

3
3
1 4 3
1
15
2
3 5

Output

1
2
-1
2
1 2

Note

There are three test cases in the example.

In the first test case, you can choose the subset consisting of only the second element. Its sum is 44 and it is even.

In the second test case, there is only one non-empty subset of elements consisting of the first element, however sum in it is odd, so there is no solution.

In the third test case, the subset consisting of all array’s elements has even sum.

题意:

给定数组 a,求出它一个和为偶数的的非空子集。

对于每组数据,如果有解,在第一行输出 k,表示你找到的非空子集的大小。在第二行输出 k个正整数,表示你找到的非空子集在 a* 数组中的下标。

如果无解,在第一行输出 −1。

解决:

偶数=偶数

奇+奇=偶数

则:在数组中先找偶数,如果能够找到偶数则直接输出即可。

如果找不到偶数那么找奇数,第一个奇数出现时先记录位置,如果出现了第二个奇数那么就把这两个输出即可。

如果均不满足则输出-1,用flag判断。

Code

#include <iostream>
using namespace std;

int a[101];
int main(){
    
    
	int t;
	int n;
	int j1,j2;
	int flag;
	cin>>t;
	while(t--){
    
    
		flag=0,j1=0;
		cin>>n;
		for(int i=1;i<=n;i++)
			cin>>a[i];
		for(int i=1;i<=n;i++){
    
    
			if(a[i]%2==0){
    
    
				cout<<"1"<<endl;
				cout<<i<<endl;
				flag=1;
				break;
			}else if(j1==0){
    
    
				j1=i;
			}else{
    
    
				j2=i;
				flag=1;
				cout<<"2"<<endl;
			cout<<j1<<" "<<j2<<endl;
				break;
			}
		}
		if(flag==0)
		cout<<"-1"<<endl;
	}
}

Kefa and First Steps

Kefa decided to make some money doing business on the Internet for exactly n days. He knows that on the i-th day (1 ≤ i ≤ n) he makes a**i money. Kefa loves progress, that’s why he wants to know the length of the maximum non-decreasing subsegment in sequence a**i. Let us remind you that the subsegment of the sequence is its continuous fragment. A subsegment of numbers is called non-decreasing if all numbers in it follow in the non-decreasing order.

Help Kefa cope with this task!

Input

The first line contains integer n (1 ≤ n ≤ 105).

The second line contains n integers a1,  a2,  …,  a**n (1 ≤ a**i ≤ 109).

Output

Print a single integer — the length of the maximum non-decreasing subsegment of sequence a.

Examples

Input

6
2 2 1 3 4 1

Output

3

Input

3
2 2 9

Output

3

Note

In the first test the maximum non-decreasing subsegment is the numbers from the third to the fifth one.

In the second test the maximum non-decreasing subsegment is the numbers from the first to the third one.

题意:

求最大非递减序列的长度

解决思路:

首先定义一个maxx统计最长的长度,然后通过如果非递减则dp[i]=dp[i]+1,长度加一,如果开始减了那么此处就把dp设置为1,因为

1 2 3 1 2

当遇到第二个1的时候,长度就要从1开始计数了。

Code

#include<iostream>
using namespace std;
int main(){
    
    
	int n;
	cin>>n;
	int a[100001];
	int dp[100001];
	for(int i=0;i<n;i++)
	{
    
    
		cin>>a[i];
	}
	dp[0]=1;
	for(int i=1;i<n;i++)
	{
    
    
		if(a[i]==a[i-1]||a[i]>a[i-1])
		{
    
    
			dp[i]=dp[i-1]+1;
		}
		else dp[i]=1;
	}
	int maxx=0;
	for(int i=0;i<n;i++)
	{
    
    
		maxx=max(maxx,dp[i]);
	}
	cout<<maxx<<endl;
} 

Filling Diamonds

You have integer nn. Calculate how many ways are there to fully cover belt-like area of 4n−24n−2 triangles with diamond shapes.

Diamond shape consists of two triangles. You can move, rotate or flip the shape, but you cannot scale it.

2 coverings are different if some 2 triangles are covered by the same diamond shape in one of them and by different diamond shapes in the other one.

Please look at pictures below for better understanding.

在这里插入图片描述

On the left you can see the diamond shape you will use, and on the right you can see the area you want to fill.

在这里插入图片描述

These are the figures of the area you want to fill for n=1,2,3,4

You have to answer tt independent test cases.

Input

The first line contains a single integer tt (1≤t≤104 — the number of test cases.

Each of the next tt lines contains a single integer n (1≤n≤109).

Output

For each test case, print the number of ways to fully cover belt-like area of 4n−24n−2 triangles using diamond shape. It can be shown that under given constraints this number of ways doesn’t exceed 10181018.

Example

Input

2
2
1

Output

2
1

Note

In the first test case, there are the following 2 ways to fill the area:

在这里插入图片描述

题意:

给定一个数字 n* ,要求你用 nn 个菱形去填满 4n−2 个正三角形。求有多少种不同的填法。

解决:

以n=1,2,3,4为例

n=1时只有一种

n=2时如上图所示:红色的已经固定故可以有蓝色和绿色两种更替再加一种即变换红色的位置

n=3时再n=2的基础上重复n=2的操作,即变化红色的位置

故dp[i]=dp[i-1]+1即n

Code

#include<iostream>
#include<cstdio>
using namespace std;
int main(){
    
    
	int T;
	scanf("%d",&T); 
	while(T--){
    
    
 	int n;
 	scanf("%d",&n); 
 	cout<<n<<endl;
 }
} 

Sasha and His Trip、

Sasha is a very happy guy, that’s why he is always on the move. There are nn cities in the country where Sasha lives. They are all located on one straight line, and for convenience, they are numbered from 1 to nn in increasing order. The distance between any two adjacent cities is equal to 1 kilometer. Since all roads in the country are directed, it’s possible to reach the city yy from the city x only if x<y.

Once Sasha decided to go on a trip around the country and to visit all nn cities. He will move with the help of his car, Cheetah-2677. The tank capacity of this model is vv liters, and it spends exactly 1 liter of fuel for 1 kilometer of the way. At the beginning of the journey, the tank is empty. Sasha is located in the city with the number 1 and wants to get to the city with the number nn. There is a gas station in each city. In the ii-th city, the price of 1 liter of fuel is ii dollars. It is obvious that at any moment of time, the tank can contain at most vv liters of fuel.

Sasha doesn’t like to waste money, that’s why he wants to know what is the minimum amount of money is needed to finish the trip if he can buy fuel in any city he wants. Help him to figure it out!

Input

The first line contains two integers n and vv (2≤n≤100, 1≤v≤100) — the number of cities in the country and the capacity of the tank.

Output

Print one integer — the minimum amount of money that is needed to finish the trip.

Examples

Input

4 2

Output

4

Input

7 6

Output

6

Note

In the first example, Sasha can buy 2liters for 2 dollars (1 dollar per liter) in the first city, drive to the second city, spend 1 liter of fuel on it, then buy 1 liter for 2 dollars in the second city and then drive to the 4-th city. Therefore, the answer is 1+1+2=4.

In the second example, the capacity of the tank allows to fill the tank completely in the first city, and drive to the last city without stops in other cities.

题意和解法:

你有一个油箱容积为V的车,每从第ii个城市到第i+1个城市需要耗费一个单位的油,在第i个城市加油为i元每个单位,问从1号城市到n号城市最少花费。
题解:很明显的一个贪心,毕竟我们尽量早加油,因为费用便宜

先计算当前v能跑到哪里如果能跑完就不再后面加了,如果跑不到n,那就通过n和v计算出差的数量,然后尽量早加油,所以刚开始走一公里就加油一次,直到剩下的油够用了。

Code

#include<iostream>
#include<cstdio>
using namespace std;
int main(){
    
    
	int n,v;
	cin>>n>>v;
	n--;
	if(v>=n)
	{
    
    
	cout<<n<<endl;
	return 0;
	}
	int dp[101];
	dp[0]=v;
	int res=n-v;
	for(int i=1;i<=res;i++)
	{
    
    
		dp[i]=dp[i-1]+i+1;
	}
	cout<<dp[res]<<endl;
} 

Joysticks

Friends are going to play console. They have two joysticks and only one charger for them. Initially first joystick is charged at a1 percent and second one is charged at a2 percent. You can connect charger to a joystick only at the beginning of each minute. In one minute joystick either discharges by 2 percent (if not connected to a charger) or charges by 1 percent (if connected to a charger).

Game continues while both joysticks have a positive charge. Hence, if at the beginning of minute some joystick is charged by 1 percent, it has to be connected to a charger, otherwise the game stops. If some joystick completely discharges (its charge turns to 0), the game also stops.

Determine the maximum number of minutes that game can last. It is prohibited to pause the game, i. e. at each moment both joysticks should be enabled. It is allowed for joystick to be charged by more than 100 percent.

Input

The first line of the input contains two positive integers a1 and a2 (1 ≤ a1, a2 ≤ 100), the initial charge level of first and second joystick respectively.

Output

Output the only integer, the maximum number of minutes that the game can last. Game continues until some joystick is discharged.

Examples

Input

3 5

Output

6

Input

4 4

Output

5

Note

In the first sample game lasts for 6 minute by using the following algorithm:

  • at the beginning of the first minute connect first joystick to the charger, by the end of this minute first joystick is at 4%, second is at 3%;
  • continue the game without changing charger, by the end of the second minute the first joystick is at 5%, second is at 1%;
  • at the beginning of the third minute connect second joystick to the charger, after this minute the first joystick is at 3%, the second one is at 2%;
  • continue the game without changing charger, by the end of the fourth minute first joystick is at 1%, second one is at 3%;
  • at the beginning of the fifth minute connect first joystick to the charger, after this minute the first joystick is at 2%, the second one is at 1%;
  • at the beginning of the sixth minute connect second joystick to the charger, after this minute the first joystick is at 0%, the second one is at 2%.

After that the first joystick is completely discharged and the game is stopped.

题意:

你有两个手机,和一个充电器,如果手机插上充电器,每秒涨%1的电,如果不插充电器,每秒掉%2的电

问你最多能维持多久两个手机都有电。

可以超过100%

解决::

策略就是每次都给当前电量少的那个充电

注意一个坑就是两个电量都是1%的情况下,虽然还有电量,但是选择任意一个电量充电另一个都会没有电,游戏也会结束。

故通过递归找到转移方程

if(a1>a2)swap(a1,a2);
return fun(a1+1,a2-2)+1;

Code

#include<iostream>
#include<cstdio>
using namespace std;

int fun(int a1,int a2){
    
    
    if(a1==0||a2==0||a1<0||a2 <0||(a2==1&&a1==1))return 0;
    else{
    
    
        if(a1>a2)swap(a1,a2);
        return fun(a1+1,a2-2)+1;
    }
}

int main(){
    
    
    int a1,a2;
    scanf("%d%d", &a1,&a2);
      cout<<fun(a1, a2)<<endl;
}

Long Jumps

Polycarp found under the Christmas tree an array aa of nn elements and instructions for playing with it:

  • At first, choose index ii (1≤i≤n) — starting position in the array. Put the chip at the index i (on the value ai).
  • While i≤ni≤n, add aiai to your score and move the chip aiai positions to the right (i.e. replace i with i+ai).
  • If i>n, then Polycarp ends the game.

For example, if n=5n=5 and a=[7,3,1,2,3]a=[7,3,1,2,3], then the following game options are possible:

  • Polycarp chooses i=1i=1. Game process: i=1⟶+78. The score of the game is: a1=7.
  • Polycarp chooses i=2i=2. Game process: i=2⟶+35⟶+38. The score of the game is: a2+a5=6
  • Polycarp chooses i=3i=3. Game process: i=3⟶+14⟶+26. The score of the game is: a3+a4=3
  • Polycarp chooses i=4i=4. Game process: i=4⟶+26. The score of the game is: a4=2
  • Polycarp chooses i=5i=5. Game process: i=5⟶+38. The score of the game is: a5=3

Help Polycarp to find out the maximum score he can get if he chooses the starting index in an optimal way.

Input

The first line contains one integer tt (1≤t≤104) — the number of test cases. Then tt test cases follow.

The first line of each test case contains one integer nn (1≤n≤2⋅105) — the length of the array aa.

The next line contains nn integers a1,a2,…,an (1≤ai≤109) — elements of the array aa.

It is guaranteed that the sum of nn over all test cases does not exceed 2⋅105

Output

For each test case, output on a separate line one number — the maximum score that Polycarp can get by playing the game on the corresponding array according to the instruction from the statement. Note that Polycarp chooses any starting position from 11 to nn in such a way as to maximize his result.

Example

Input

4
5
7 3 1 2 3
3
2 1 4
6
2 1000 2 3 995 1
5
1 1 1 1 1

Output

7
6
1000
5

Note

The first test case is explained in the statement.

In the second test case, the maximum score can be achieved by choosing i=1

In the third test case, the maximum score can be achieved by choosing i=2

In the fourth test case, the maximum score can be achieved by choosing i=1

解决:

  • i + a[i] > n ,这时其得分 ans = a[i]。

  • i + a[i] <= n ,这时游戏并未结束 i = i + a[i] , 得分dp[i]+= a[i] ,并进行下一轮,直到i + a[i] > n为止。

    如果我们从 i = n 开始遍历,并将a[i] 的得分储存在 a[i] 中,即使出现 i + a[i] <= n的情况 ,其a[i+a[i]]的得分已经计算好,不需要从头开始计算。

Code

#include <iostream>
using namespace std;
int a[200005];
long long dp[200005];
int main(){
    
    
    int t;
    scanf("%d",&t);
    while(t--){
    
    
        int n;
        scanf("%d",&n);       
        for(int i=1;i<=n;i++){
    
    
            scanf("%d",&a[i]);
            dp[i]=0;
        }
        long long ans = 0;
        for(int i=n;i>=1;i--){
    
    
            if(i+a[i]<=n)dp[i]=dp[i+a[i]]+a[i];
            else dp[i] = a[i];
            ans = max(ans,dp[i]);
        }
        printf("%lld\n", ans);
    }
}

Flipping Game

Iahub got bored, so he invented a game to be played on paper.

He writes n integers a1, a2, …, a**n. Each of those integers can be either 0 or 1. He’s allowed to do exactly one move: he chooses two indices i and j (1 ≤ i ≤ j ≤ n) and flips all values a**k for which their positions are in range [i, j] (that is i ≤ k ≤ j). Flip the value of x means to apply operation x = 1 - x.

The goal of the game is that after exactly one move to obtain the maximum number of ones. Write a program to solve the little game of Iahub.

Input

The first line of the input contains an integer n (1 ≤ n ≤ 100). In the second line of the input there are n integers: a1, a2, …, a**n. It is guaranteed that each of those n values is either 0 or 1.

Output

Print an integer — the maximal number of 1s that can be obtained after exactly one move.

Examples

Input

5
1 0 0 1 0

Output

4

Input

4
1 0 0 1

Output

4

Note

In the first case, flip the segment from 2 to 5 (i = 2, j = 5). That flip changes the sequence, it becomes: [1 1 1 0 1]. So, it contains four ones. There is no way to make the whole sequence equal to [1 1 1 1 1].

In the second case, flipping only the second and the third element (i = 2, j = 3) will turn all numbers into 1.

思路:

前缀和求出来,然后遍历每个区间,区间前面的1和区间后面的1以及反转后的1的个数即1的个数,统计最长的max。

区间DP:

预处理差不多,DP[i][j]表示I到j之间一次翻转后一最多的数量。
对于每个区间而言,在中间找个断点
k
,一次翻转可能发生在前面IK,也可能发生在Kj之间,
那我们就得到了状态转移方程

dp[I][j]=max(dp[i][k]+sum[j]-sum[k],dp[k+1][j]+sum[k]-sum[i-1]));

Code

#include<cstdio> 
#include<iostream>
using namespace std;

int n,ans;
int s[110],a[110]; 
int main()
{
    
    
	cin>>n; 
	for(int i=1;i<=n;i++)
	cin>>a[i],s[i]=s[i-1]+a[i];
	
	for(int i=1;i<=n;++i) 
	{
    
    
		for(int j=i;j<=n;++j)
		ans=max(ans,(j-i+1)-(s[j]-s[i-1])+s[i-1]+s[n]-s[j]);
	}
	printf("%d\n",ans);
	
	return 0;
}

导弹拦截

题目描述

某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统。但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度。某天,雷达捕捉到敌国的导弹来袭。由于该系统还在试用阶段,所以只有一套系统,因此有可能不能拦截所有的导弹。
输入导弹依次飞来的高度(雷达给出的高度数据是\le 50000≤50000的正整数),计算这套系统最多能拦截多少导弹,如果要拦截所有导弹最少要配备多少套这种导弹拦截系统。

输入格式

1行,若干个整数(个数\le 100000≤100000)

输出格式

2行,每行一个整数,第一个数字表示这套系统最多能拦截多少导弹,第二个数字表示如果要拦截所有导弹最少要配备多少套这种导弹拦截系统。

输入输出样例

输入

cpp 389 207 155 300 299 170 158 65

输出

cpp 6 2

说明/提示

为了让大家更好地测试n方算法,本题开启spj,n方100分,nlogn200分

每点两问,按问给分

Code

在这里插入代码片

猜你喜欢

转载自blog.csdn.net/weixin_45822638/article/details/113002537