标签:data represent cli 动态规划 math point microsoft accept lan
| Time Limit: 5000MS | Memory Limit: 65536K | |
| Total Submissions: 4318 | Accepted: 1745 |
Description
Input
Output
Sample Input
2 9 1 2 2 2 2 3 3 3 1 1 1
Sample Output
Case 1: 29 Case 2: 1
递归形式的动态规划:dp[st][ed][len]从st到ed全然消除。且ed右边挨着有一个len的大块颜色和ed同样.
一种消除方式是,Len块直接和ed块合并直接消除得到分数work(st,ed-1,0)+(a[ed].n+len)*(a[ed].n+len);
还有一种是在st到ed之间找到一个块p和ed块颜色同样,把这3块直接合并 work(st,p,a[ed].n+len)+work(p+1,ed-1,0);
两种方式取最大的值。
当st==ed时递归结束。
#include<stdio.h>
#include<math.h>
#include<string.h>
#include<stdlib.h>
#include<algorithm>
#include<queue>
using namespace std;
#define LL __int64
#define N 210
const int inf=0x1f1f1f1f;
struct node
{
int c,n,p;
}a[N];
int f[N][N][N];
int work(int st,int ed,int len)
{
if(f[st][ed][len])
return f[st][ed][len];
int i,ans=(a[ed].n+len)*(a[ed].n+len);
if(st==ed)
{
f[st][ed][len]=ans;
return ans;
}
ans+=work(st,ed-1,0);
for(i=ed-1;i>=st;i--)
{
if(a[i].c!=a[ed].c)
continue;
int tmp=work(st,i,a[ed].n+len)+work(i+1,ed-1,0);
if(tmp<=ans)
continue;
ans=tmp;
break;
}
f[st][ed][len]=ans;
return ans;
}
int main()
{
int T,t,cnt,i,n,Cas=1;
scanf("%d",&T);
while(T--)
{
memset(a,0,sizeof(a));
scanf("%d",&n);
scanf("%d",&t);
cnt=0;
a[cnt].c=t;
a[cnt].n=1;
for(i=1;i<n;i++)
{
scanf("%d",&t);
if(t==a[cnt].c)
{
a[cnt].n++;
}
else
{
cnt++;
a[cnt].c=t;
a[cnt].n=1;
}
}
memset(f,0,sizeof(f));
printf("Case %d: %d\n",Cas++,work(0,cnt,0));
}
return 0;
}
标签:data represent cli 动态规划 math point microsoft accept lan
原文地址:http://www.cnblogs.com/gavanwanggw/p/7136613.html