您的位置:首页 > 其它

【动态规划】XMU 1560 新ACM规则

2016-04-24 12:52 302 查看
[b]题目链接:[/b]

  http://acm.xmu.edu.cn/JudgeOnline/problem.php?id=1560

[b]题目大意:[/b]

  给定n(n<=200)个任务及每个任务的耗时,问m(m<=200)时间能够获得的最大收益(收益为解决连续任务数的平方的和,具体例子见题目)

[b]题目思路:[/b]

  【动态规划】

  设f[i][j]表示前i个任务,当前时间为j的最优值。

  枚举第i个任务是前有几个和i连续的任务,状态转移方程很好推。

  时间复杂度比O(n3)小很多,大概O(n2)级别。

//
//by coolxxx
//
#include<iostream>
#include<algorithm>
#include<string>
#include<iomanip>
#include<memory.h>
#include<time.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<stdbool.h>
#include<math.h>
#define min(a,b) ((a)<(b)?(a):(b))
#define max(a,b) ((a)>(b)?(a):(b))
#define abs(a) ((a)>0?(a):(-(a)))
#define lowbit(a) (a&(-a))
#define sqr(a) ((a)*(a))
#define swap(a,b) ((a)^=(b),(b)^=(a),(a)^=(b))
#define eps 1e-8
#define J 10000
#define MAX 0x7f7f7f7f
#define PI 3.1415926535897
#define N 204
using namespace std;
int n,m,lll,ans,cas;
int a
,sum
;
int f

;
int main()
{
#ifndef ONLINE_JUDGE
//    freopen("1.txt","r",stdin);
//    freopen("2.txt","w",stdout);
#endif
int i,j,k;
scanf("%d",&cas);
while(cas--)
//    while(~scanf("%s",s1))
//    while(~scanf("%d",&n))
{
scanf("%d%d",&n,&m);
memset(sum,0,sizeof(sum));
memset(f,0,sizeof(f));
for(i=1;i<=n;i++)
{
scanf("%d",&a[i]);
sum[i]=sum[i-1]+a[i];
}
for(i=1;i<=n;i++)f[i][a[i]]=1;
for(i=1;i<=n;i++)
{
for(j=0;j<=m;j++)f[i][j]=max(f[i][j],f[i-1][j]);
for(j=a[i];j<=m;j++)
{
f[i][j]=max(f[i][j],f[i][j-1]);
for(k=i;k && j>=sum[i]-sum[k-1];k--)
{
f[i][j]=max(f[i][j],f[k-1][j-sum[i]+sum[k-1]]+sqr(i-k+1));
}
}
}
printf("%d\n",f
[m]);
}
return 0;
}

/*
//

//
*/


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: