TOJ 1717 WOJ

描述

Alex likes solving problems on WOJ (http://acm.whu.edu.cn/oak). As we all know, a beautiful balloon will appears when a problem is solved. Alex loves balloons, especially when they're in a consecutive column, from which he can get a sense of accomplishment. Problems on WOJ have a variety of difficulties. Hard problems cost more time, while easy ones may be "killed in 1 second". Now we know that WOJ has N problems, numbered from 1 to N. Alex calls the solved problems in one consecutive column as a "successful string". The length of a successful string is the number of problems it contains. Also he defines the value of a successful string as the square of the string's length. Alex hopes to solve a certain number of problems in M time, so he can get some successful strings, now he wants to maximize the sum of all the strings' value.
TOJ 1717 WOJ_第1张图片

输入

The input consists of multiple test cases. The first line of input contains an integer T, which is the number of test cases.

The input consists of several test cases. Each test case starts with a line containing two integers N and M. Each of the following N lines contains a single integer Mi indicating the time cost on solving the i-th problem.(1<=N, M<=100)

[Technical Specification]
T is an integer, and T <= 15;
N and M are integers, 1 <= N, M <= 100.
Mi are integers and, 0 <= Mi <= 100

输出

For each test case, print a single line containing a number indicating the maximum sum. 

样例输入

1
10 9
6
1
3
1
5
3
2
5
5
5

样例输出

10

题目来源

4th Baidu Cup Central China

 

记忆化DP,参考了大牛的代码,不过没有注释看的累。

置底向上对问题进行求解,每一次解得

k1:如果该层的m>=mi,则连续的层数+1。

k2:当然也可以选择不加,那么层数变为0。

选择k1,k2中比较大的值。

 

代码中有两处地方:

1)为什么是k>n返回,而不是k==n时候返回。是因为每一次的计算是下层开始计算的。

2)为什么每次连续累加2*se-1。因为等差数列的变形 (1+2+3+4+...+n)*2-n=n*n => (1*2-1)+(2*2-1)+(3*2-1)+...+(n*2-1)

http://blog.csdn.net/yobobobo/article/details/7657047

 

#include <stdio.h>
#include <string.h>
#define MAXN 105

int n,m; 
int dp[MAXN][MAXN][MAXN];
int mi[MAXN];

int max(int a, int b){
	if(a>b)return a;
	else return b;
}
int dfs(int k, int m, int se){
	if(dp[k][m][se])return dp[k][m][se]; 
	if(k>n)return 0;
	int ans,k1=0,k2=0;
	if(m-mi[k]>=0){
		k1=dfs(k+1,m-mi[k],se+1);
	}
	k2=dfs(k+1,m,0);	
	ans=max(k1,k2);
	if(!se){
		return dp[k][m][se]=ans; 
	}else{
		return dp[k][m][se]=se*2-1+ans;
	}
}

int main(int argc, char *argv[])
{
	int t;
	scanf("%d",&t);
	while(t--){
		memset(dp,0,sizeof(dp));
		scanf("%d%d",&n,&m);
		for(int i=0; i<n; i++){
			scanf("%d",&mi[i]);
		}
		dfs(0,m,0);
		printf("%d\n",dp[0][m][0]);
	} 
	return 0;
}

 

你可能感兴趣的:(OJ)