这是到动态规划的题目,属于有顺序的0 1 背包问题;
代码:
#include<stdio.h>
#include<string.h> int d[][]; //d[i][j]
int a[];
int N; int max(int a, int b)
{
return a>b?a:b;
} int solve(int i,int high)
{
if(d[i][high]>=)
return d[i][high];
if(i==N)
{
if(a[i]<high)
return d[N][high]=;
else
return d[N][high]=;
}
if(a[i]<high)
return d[i][high]=max(solve(i+,a[i])+,solve(i+,high)); //打击和不打击 取大者
else
return d[i][high]=solve(i+,high);
} int main()
{
int T;
scanf("%d",&T);
while(T--)
{
memset(d,-,sizeof(d));
scanf("%d",&N);
for(int i=; i<=N; i++)
{
scanf("%d",&a[i]);
}
printf("%d\n",solve(,));
}
return ;
}
但这个代码提交会得到RE,至于为什么可能是记忆话搜索对这个的复杂度减小的比较小,所以递归深度太深,造成堆栈溢出。
我想多了,不是这个原因,是我没有注意到下标越界了。
AC代码:
#include<stdio.h>
#include<string.h> int d[][]; //d[i][j]
int a[];
int N; int max(int a, int b)
{
return a>b?a:b;
} int solve(int i,int high)
{
if(d[i][high]>=)
return d[i][high];
if(i==N)
{
if(a[i]<high)
return d[N][high]=;
else
return d[N][high]=;
}
if(a[i]<high)
return d[i][high]=max(solve(i+,a[i])+,solve(i+,high)); //打击和不打击 取大者
else
return d[i][high]=solve(i+,high);
} int main()
{
int T;
scanf("%d",&T);
while(T--)
{
memset(d,-,sizeof(d));
scanf("%d",&N);
for(int i=; i<=N; i++)
{
scanf("%d",&a[i]);
}
printf("%d\n",solve(,));
}
return ;
}
我不知道原来这种问题叫 最长递增子序列问题 我还给他起了个(顺序0 1 背包问题),我这就透过本质起的名字。
最长字串问题 (NYOJ - 17)
AC代码:
#include<stdio.h>
#include<stdlib.h>
#include<string.h> int d[][];
char a[];
int N; int max(int a, int b)
{
return a>b?a:b;
} int dp(int i, char c)
{
if(d[i][c]>=)
return d[i][c];
if(i==N-)
{
if(a[i]>c)
return d[i][c] = ;
else
return d[i][c] = ;
}
if(a[i]>c)
return d[i][c]=max(dp(i+,c),dp(i+,a[i])+);
else
return d[i][c]=dp(i+,c);
} int main()
{
int T;
scanf("%d",&T);
while(T--)
{
memset(d,-,sizeof(d));
scanf("%s",a);
N = strlen(a);
printf("%d\n",dp(,));
}
return ;
}