暑假训练第一周限时训练二

**HDU - 2674 **
WhereIsHeroFrom: Zty, what are you doing ?
Zty: I want to calculate N!..
WhereIsHeroFrom: So easy! How big N is ?
Zty: 1 <=N <=1000000000000000000000000000000000000000000000…
WhereIsHeroFrom: Oh! You must be crazy! Are you Fa Shao?
Zty: No. I haven’s finished my saying. I just said I want to calculate N! mod 2009

Hint : 0! = 1, N! = N*(N-1)!
Input
Each line will contain one integer N(0 <= N<=10^9). Process to end of file.
Output
For each case, output N! mod 2009
Sample Input
4
5
Sample Output
24
120

打表找规律题

#include<iostream>
#include<string.h>
#include<algorithm>
#include<string>
#include<stdio.h>
using namespace std;
int a[10000];



int main(){
	int n;
	a[0]=1;a[1]=1;a[2]=2;a[3]=6;a[4]=24;a[5]=120;a[6]=720;a[7]=1022;a[8]=140;a[9]=1260;a[10]=546;a[11]=1988;a[12]=1757;a[13]=742;a[14]=343;a[15]=1127;a[16]=1960;a[17]=1176;a[18]=1078;a[19]=392;a[20]=1813;a[21]=1911;a[22]=1862;a[23]=637;a[24]=1225;a[25]=490;a[26]=686;a[27]=441;a[28]=294;a[29]=490;a[30]=637;a[31]=1666;a[32]=1078;a[33]=1421;a[34]=98;a[35]=1421;a[36]=931;a[37]=294;a[38]=1127;a[39]=1764;a[40]=245;
	while(~scanf("%d",&n)){
		if(n>40) printf("0\n");
		else printf("%d\n",a[n]);
	}
}

LightOJ - 1214

Given two integers, a and b, you should check whether a is divisible by b or not. We know that an integer a is divisible by an integer b if and only if there exists an integer c such that a = b * c.
Input
Input starts with an integer T (≤ 525), denoting the number of test cases.
Each case starts with a line containing two integers a (-10200 ≤ a ≤ 10200) and b (|b| > 0, b fits into a 32 bit signed integer). Numbers will not contain leading zeroes.
Output
For each case, print the case number first. Then print ‘divisible’ if a is divisible by b. Otherwise print ‘not divisible’.
Sample Input
6
101 101
0 67
-101 101
7678123668327637674887634 101
11010000000000000000 256
-202202202202000202202202 -101
Sample Output
Case 1: divisible
Case 2: divisible
Case 3: divisible
Case 4: not divisible
Case 5: divisible
Case 6: divisible

#include<iostream>
#include<string.h>
#include<algorithm>
#include<string>
#include<stdio.h>
using namespace std;
string s;

int main(){
	int t;
	scanf("%d",&t);
	for(int k=1;k<=t;k++){
		cin>>s;
		int n=s.size();
		int b;
		scanf("%d",&b);
		if(b<0) b=-b;
		long long tem=0;
		for(int i=0;i<=n-1;i++){
			if(s[i]=='-') continue;
			tem=tem*10+(s[i]-'0');
			tem=tem%b;
		}
		if(tem==0) printf("Case %d: divisible\n",k);
		else printf("Case %d: not divisible\n",k);
	}
}

边乘边取模

OpenJ_Bailian - 2995

五一到了,PKU-ACM队组织大家去登山观光,队员们发现山上一个有N个景点,并且决定按照顺序来浏览这些景点,即每次所浏览景点的编号都要大于前一个浏览景点的编号。同时队员们还有另一个登山习惯,就是不连续浏览海拔相同的两个景点,并且一旦开始下山,就不再向上走了。队员们希望在满足上面条件的同时,尽可能多的浏览景点,你能帮他们找出最多可能浏览的景点数么?
Input
Line 1: N (2 <= N <= 1000) 景点数
Line 2: N个整数,每个景点的海拔
Output
最多能浏览的景点数
Sample Input
8
186 186 150 200 160 130 197 220
Sample Output
4

显而易见就是两边最长上升子序列

#include<iostream>
#include<string.h>
#include<algorithm>
#include<string>
#include<stdio.h>
using namespace std;
int dp[1009];
int dp2[1009];
int sum[1009];
int a[1009];

int main(){
	int n;
	while(~scanf("%d",&n)){
		memset(dp,0,sizeof(dp));
		for(int i=1;i<=n;i++){
			scanf("%d",&a[i]);
			dp[i]=1;
		}
		for(int i=1;i<=n;i++){
			for(int j=1;j<i;j++){
				if(a[j]<a[i]&&dp[i]<dp[j]+1) dp[i]=dp[j]+1;
			}
		}
		for(int i=n;i>=1;i--){
			dp2[i]=1;
			for(int j=n;j>i;j--){
				if(a[i]>a[j]&&dp2[i]<dp2[j]+1) dp2[i]=dp2[j]+1;
			}
//			printf("dp2[%d]:%d\n",i,dp2[i]);
		}
		int maxn=0;
		for(int i=1;i<=n;i++){
			sum[i]=dp[i]+dp2[i]-1;
			maxn=max(maxn,sum[i]);
		}
		cout<<maxn<<endl;
	}
}

ZOJ - 4019

恐怖的魔术背包
每次拿物品得到的价值是一个定值
剩余空间*常数
那么肯定先拿体积小的鸭
那么放背包1还是背包2呢
开二维dp暴力出所有情况

#include<iostream>
#include<string.h>
#include<algorithm>
#include<string>
#include<stdio.h>
using namespace std;
long long dp[2008][2008];
int a[2008];
int b[2008];
long long suma[2008];
long long sumb[2008];

int main(){
	int ca;
	scanf("%d",&ca);
	while(ca--){
		int k1,k2,c;
		scanf("%d%d%d",&k1,&k2,&c);
		int n,m;
		scanf("%d%d",&n,&m);
		for(int i=1;i<=n;i++){
			scanf("%d",&a[i]);
		}
		for(int i=1;i<=m;i++)
			scanf("%d",&b[i]);
		sort(a+1,a+1+n);
		sort(b+1,b+1+m);
		for(int i=0;i<=n;i++){
			for(int j=0;j<=m;j++)
				dp[i][j]=0;
		}
		dp[0][0]=0;
		long long maxn=0;
		for(int i=1;i<=n;i++) 
			suma[i]=suma[i-1]+a[i];
		for(int i=1;i<=m;i++)
			sumb[i]=sumb[i-1]+b[i];
		for(int i=1;i<=n;i++){
			if(suma[i]<=c) dp[i][0]=max(dp[i][0],dp[i-1][0]+(c-suma[i])*k1);
			maxn=max(maxn,dp[i][0]);
		}	
		for(int j=1;j<=m;j++){
			if(sumb[j]<=c) dp[0][j]=max(dp[0][j],dp[0][j-1]+(c-sumb[j])*k2);
			maxn=max(maxn,dp[0][j]);
		}
		for(int i=1;i<=n;i++){
			for(int j=1;j<=m;j++){
				if(suma[i]+sumb[j]<=c)  dp[i][j]=max(dp[i][j],dp[i-1][j]+(c-suma[i]-sumb[j])*k1);
				if(suma[i]+sumb[j]<=c)  dp[i][j]=max(dp[i][j],dp[i][j-1]+(c-sumb[j]-suma[i])*k2);					
				maxn=max(maxn,dp[i][j]);
			}
		}
		printf("%lld\n",maxn);
	}
		
}

ZOJ - 3211

JAVAMAN is visiting Dream City and he sees a yard of gold coin trees. There are n trees in the yard. Let’s call them tree 1, tree 2 …and tree n. At the first day, each tree i has ai coins on it (i=1, 2, 3…n). Surprisingly, each tree i can grow bi new coins each day if it is not cut down. From the first day, JAVAMAN can choose to cut down one tree each day to get all the coins on it. Since he can stay in the Dream City for at most m days, he can cut down at most m trees in all and if he decides not to cut one day, he cannot cut any trees later. (In other words, he can only cut down trees for consecutive m or less days from the first day!)
Given n, m, ai and bi (i=1, 2, 3…n), calculate the maximum number of gold coins JAVAMAN can get.

Input

There are multiple test cases. The first line of input contains an integer T (T <= 200) indicates the number of test cases. Then T test cases follow.
Each test case contains 3 lines: The first line of each test case contains 2 positive integers n and m (0 < m <= n <= 250) separated by a space. The second line of each test case contains n positive integers separated by a space, indicating ai. (0 < ai <= 100, i=1, 2, 3…n) The third line of each test case also contains n positive integers separated by a space, indicating bi. (0 < bi <= 100, i=1, 2, 3…n)

Output

For each test case, output the result in a single line.

Sample Input

2
2 1
10 10
1 1
2 2
8 10
2 3

Sample Output

10
21

Hint
s:
Test case 1: JAVAMAN just cut tree 1 to get 10 gold coins at the first day.
Test case 2: JAVAMAN cut tree 1 at the first day and tree 2 at the second day to get 8 + 10 + 3 = 21 gold coins in all.

给你n棵树,每个树有个初始果实值ai,每天增长值bi
你要在m天内每天砍一棵树(砍下即得到全部果实值)
求m天内得到最大果实值。

把增长快的放在后面选

#include<iostream>
#include<string.h>
#include<algorithm>
#include<string>
#include<stdio.h>
using namespace std;
int dp[260][260];
struct node{
	int a;
	int b;
}t[260];

bool cmp(node a,node b){
	if(a.b==b.b) return a.a<b.a;
	return a.b<b.b;
}

int main(){
	int k;
	scanf("%d",&k);
	while(k--){
		memset(dp,-1,sizeof(dp));
		int n,m;
		scanf("%d%d",&n,&m);
		for(int i=1;i<=n;i++) scanf("%d",&t[i].a);
		for(int i=1;i<=n;i++) scanf("%d",&t[i].b);
		sort(t+1,t+1+n,cmp);
		dp[1][m]=0;
		int maxn=0;
		for(int i=1;i<=n;i++){
			for(int j=0;j<=m;j++){
				if(dp[i][j]!=-1){
					dp[i+1][j]=max(dp[i+1][j],dp[i][j]);
					if(j-1>=0) dp[i+1][j-1]=max(dp[i+1][j-1],dp[i][j]+(m-j)*t[i].b+t[i].a);
				}
			}
		}
		for(int i=0;i<=m;i++) maxn=max(maxn,dp[n+1][i]);
		cout<<maxn<<endl;
	}
	}

ZOJ - 2955
Recently, Dearboy buys a dart for his dormitory, but neither Dearboy nor his roommate knows how to play it. So they decide to make a new rule in the dormitory, which goes as follows:
Given a number N, the person whose scores accumulate exactly to N by the fewest times wins the game.
Notice once the scores accumulate to more than N, one loses the game.
Now they want to know the fewest times to get the score N.

So the task is :
Given all possible dart scores that a player can get one time and N, you are required to calculate the fewest times to get the exact score N.

Input

Standard input will contain multiple test cases. The first line of the input is a single integer T (1 <= T <= 50) which is the number of test cases. And it will be followed by T consecutive test cases.
Each test case begins with two positive integers M(the number of all possible dart scores that a player can get one time) and N. Then the following M integers are the exact possible scores in the next line.
Notice: M (0 < M < 100), N (1 < N <= 1000000000), every possible score is (0, 100).

Output

For each test case, print out an integer representing the fewest times to get the exact score N.
If the score can’t be reached, just print -1 in a line.

Sample Input

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

Sample Output

2
3
-1

一个数组 A1,A2,……AN从小到大,对于一个远大于AN的数,按题目要求来的 最优解 中,小于AN的数的个数肯定是不会大于 AN的,所以可以先对AN*AN来进行优化,得到答案的一部分,剩余的 再进行背包即可

#include<iostream>
#include<string.h>
#include<algorithm>
#include<string>
#include<stdio.h>
using namespace std;
int dp[10000];
int a[109];

int main(){
	int ca;
	scanf("%d",&ca);
	while(ca--){
		int m,n;
		scanf("%d%d",&m,&n);
		for(int i=1;i<=m;i++){
			scanf("%d",&a[i]);
		}
		sort(a+1,a+1+m);
		int tem=a[m]*a[m];
		int ans=0;
		if(n>tem){
			ans+=(n/tem)*a[m];
			n=n%tem;
		}
		memset(dp,0x3f3f3f3f,sizeof(dp));
		dp[0]=0;
		for(int i=1;i<=m;i++){
			for(int j=a[i];j<=n;j++){
				dp[j]=min(dp[j],dp[j-a[i]]+1);
			}
		}
		if(dp[n]==0x3f3f3f3f) printf("-1\n");
		else printf("%d\n",ans+dp[n]);
	}
}
已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 像素格子 设计师:CSDN官方博客 返回首页