codevs1906 最长递增子序列问题

题目描述  Description

给定正整数序列x1,..... , xn  。
(1)计算其最长递增子序列的长度s。
(2)计算从给定的序列中最多可取出多少个长度为s的递增子序列。
(3)如果允许在取出的序列中多次使用x1和xn,则从给定序列中最多可取出多少个长
度为s的递增子序列。

输入描述  Input Description

第1 行有1个正整数n,表示给定序列的长度。接
下来的1 行有n个正整数x1.....xn 。

输出描述  Output Description

第1 行是最长递增子序列的长度s。第2行是可取出的长度为s 的递增子序列个数。第3行是允许在取出的序列中多次使用x1和xn时可取出的长度为s 的递增子序列个数。

样例输入  Sample Input

4
3 6 2 5

样例输出  Sample Output

2
2
3

 

不得不吐槽codevs上面网络流24题好多数据都是很蛋疼的要输出方案又不给spj……鬼知道你数据是用哪种方案啊

啊这题还算正常

第一问LIS随便求

第二问拆点完S向所有x1连流量1费用0的边,所有x2向T连流量1费用0的边,所有x1向x2连流量1费用1的边。因为要表示有没有取这个点

对于所有a[i]

然后跑最大费用。每次增广搞完如果答案是第一问的最长长度,那么ans++。

第三问就是第二问的建图与1和n有关的边的流量全改inf就对了

#include
#include
#include
#define LL long long
#define inf 0x3ffffff
#define S 0
#define T 1001
using namespace std;
inline LL read()
{
    LL x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
int n,ans,flow,cnt,tot;
int a[510];
int mn[510];
struct edge{int from,to,next,v,c;}e[500010];
int head[1010],dis[1010],q[1010],from[1010];
bool mrk[1010];
inline void ins(int u,int v,int w,int c)
{
	e[++cnt].to=v;
	e[cnt].v=w;
	e[cnt].c=c;
	e[cnt].from=u;
	e[cnt].next=head[u];
	head[u]=cnt;
}
inline void insert(int u,int v,int w,int c)
{
	ins(u,v,w,c);
	ins(v,u,0,-c);
}
inline int bsearch(int x)
{
	int l=1,r=ans,s=0;
	while(l<=r)
	{
		int mid=(l+r)>>1l;
		if (mn[mid]<=x){s=mid;l=mid+1;}
		else r=mid-1;
	}
	return s;
}
inline bool spfa()
{
	for (int i=1;i<=T;i++)dis[i]=inf;
	memset(mrk,0,sizeof(mrk));
	int t=0,w=1;
	dis[S]=0;q[0]=S;mrk[S]=1;
	while (t!=w)
	{
		int now=q[t++];if (t==1005)t=0;
		for (int i=head[now];i;i=e[i].next)
		if (e[i].v&&dis[now]+e[i].c

 

转载于:https://www.cnblogs.com/zhber/p/4189803.html

你可能感兴趣的:(codevs1906 最长递增子序列问题)