向前走莫回头❤

【openjudge 2.6基本算法之动态规划】(合集)

1481:Maximum sum



                                  

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int f[50010][2],g[50010][2],sum[50010][2];
int n,T,a[50010];
int main()
{
	int i,j;
	scanf("%d",&T);
	while(T)
	 {
	 	memset(sum,128,sizeof(sum));
	 	memset(f,128,sizeof(f));
	 	memset(g,128,sizeof(g));
	 	int ans=f[0][0];
	 	scanf("%d",&n);
	 	for(i=1;i<=n;++i) scanf("%d",&a[i]);
	 	f[1][0]=f[1][1]=a[1]; sum[1][0]=a[1];
	 	for(i=2;i<=n;++i)
	 	 {
	 	 	int s;
	 	 	sum[i][0]=sum[i-1][0];
	 	 	f[i][1]=max(f[i-1][1],f[i-1][0])+a[i];
	 	 	f[i][0]=a[i];
	 	 	if(f[i][1]<f[i][0])  s=f[i][0];
	 	 	 else s=f[i][1];
	 	 	if(s>sum[i][0]) sum[i][0]=s;
		  }
		g[n][0]=g[n][1]=a[n]; sum[n][1]=a[n];
		for(i=n-1;i>0;--i)
		 {
		 	int s;
		 	sum[i][1]=sum[i+1][1];
		 	g[i][1]=max(g[i+1][1],g[i+1][0])+a[i];
		 	g[i][0]=a[i];
		 	if(g[i][1]<g[i][0]) s=g[i][0];
		 	 else s=g[i][1];
		 	if(s>sum[i][1]) sum[i][1]=s;
		 }
		for(i=1;i<n;++i)
		 {
		 	int s=sum[i][0]+sum[i+1][1];
		 	if(s>ans) ans=s;
		 }
		printf("%d\n",ans);
		T--;
	 }
	return 0;
}
 

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int f[10010],n,a[10010];
int main()
{
	int i,j;
	scanf("%d",&n);
	for (i=1;i<=n;i++)
	 scanf("%d",&a[i]);
	for (i=1;i<=n;i++)
	  f[i]=1;
	for (i=2;i<=n;i++)
	 for (j=1;j<i;j++)
	   if (a[j]<a[i]&&f[j]+1>f[i])
	     f[i]=f[j]+1;
	for (i=2;i<=n;i++)
	  f[i]=max(f[i-1],f[i]);
	printf("%d",f[n]);
	return 0;
} 


#include<cstdio>
#include<cstring>
using namespace std;
int n,a1,a2;
int main()
{
	int i;
	scanf("%d",&n);
	if (n==1)
	 {printf("%d",1); return 0;}
	if (n==2)
	  {printf("%d",2); return 0;}
	a1=1; a2=2;
	for (i=3;i<=n;i++)
	 {
	 	int t;
	 	t=a1+a2; a1=a2; a2=t;
	 }
	printf("%d",a2);
	return 0;
 } 


#include<cstdio>
#include<cstring>
using namespace std;
int f[30][30],n,m;
int main()
{
	int i,j;
	scanf("%d%d",&n,&m);
	for (i=1;i<=n;i++)
	 for (j=1;j<=m;j++)
	  if (i+j!=2)
	   f[i][j]+=f[i-1][j]+f[i][j-1];
	  else f[i][j]=1;
	printf("%d",f[n][m]);
	return 0;
 } 

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int a[30],n,m,ans;
bool p[30];
void dfs(int j,int sum)
{
	if (sum==m)
	  {ans++; return; }
	if (sum>m) return;
	for (int i=j;i<=n;i++)
	  if (p[i])
	    {
	     p[i]=false;
	     dfs(i,sum+a[i]);
	     p[i]=true;
		}
	return;
}
int main() 
{
	int i;
	scanf("%d%d",&n,&m);
	memset(p,true,sizeof(p));
	for (i=1;i<=n;i++)
	 scanf("%d",&a[i]);
	sort(a+1,a+n+1);
	dfs(1,0);
	printf("%d",ans);
	return 0;
}
(这题dfs就能切。。。数据弱啊!)

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
char a[1010],b[1010];
int f[1010][1010],la,lb,n;
int main()
{
	int i,j,k;
	scanf("%d",&n);
	for (k=1;k<=n;k++)
	 {
	  cin>>a>>b;
	  la=strlen(a); lb=strlen(b);
	  memset(f,0,sizeof(f));
	  for (i=1;i<=la;i++)
	    f[i][0]=i;
	  for (i=1;i<=lb;i++)
	    f[0][i]=i;
	  for (i=1;i<=la;i++)
	   for (j=1;j<=lb;j++)
	    if (a[i-1]==b[j-1])
	     f[i][j]=f[i-1][j-1];
	    else
	      f[i][j]=min(min(f[i-1][j],f[i][j-1]),f[i-1][j-1])+1;
	  printf("%d\n",f[la][lb]);
	 }
}


#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int f[110][110],a[110],n,k;
int main()
{
	int i,j;
	scanf("%d%d",&n,&k);
	for (i=1;i<=n;i++)
	 scanf("%d",&a[i]);
	for (i=1;i<=n;i++)
	 {
	 	f[i][a[i]%k]=max(f[i][a[i]%k],a[i]);
	 	for (j=0;j<k;j++)
	 	 if (f[i][j]!=0)
	 	  {
	 	  	f[i+1][(j+a[i+1])%k]=max(f[i+1][(j+a[i+1])%k],f[i][j]+a[i+1]);
	 	  	f[i+1][j]=max(f[i+1][j],f[i][j]);
		   }
	 }
	printf("%d",f[n][0]);
	return 0;
}


#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
int f[10010][100],a[10010],n,k;
int main()
{
	int i,j;
	scanf("%d%d",&n,&k);
	for (i=1;i<=n;i++)
	 scanf("%d",&a[i]);
	f[1][a[1]%k]=1;
	for (i=1;i<=n;i++)
	 for (j=0;j<k;j++)
	   if (f[i][j]!=0)
	     {
	     	f[i+1][(abs(j+a[i+1]))%k]=1;
	     	f[i+1][(abs(j-a[i+1]))%k]=1;
	     }
	if (f[n][0]!=0)
	  printf("YES");
	 else printf("NO");
	return 0;
}


#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int f[10010],a[10010],n;
int main()
{
	int i,j;
	scanf("%d",&n);
	for (i=1;i<=n;i++)
	 {
	 	scanf("%d",&a[i]);
	 	f[i]=a[i];
	 }
	for (i=2;i<=n;i++)
	 for (j=1;j<i;j++) 
	   if (a[j]<a[i]&&f[j]+a[i]>f[i])
	     f[i]=f[j]+a[i];
	for (i=2;i<=n;i++)
	  f[i]=max(f[i-1],f[i]);
	printf("%d",f[n]);
	return 0;
} 



#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int f[1010][510],tl[1010],num[1010];
int n,m,k;
int main()
{
	int i,j,l;
	scanf("%d%d%d",&n,&m,&k);
	for (i=1;i<=k;i++)
	  scanf("%d%d",&num[i],&tl[i]);
	for (l=1;l<=k;l++)
	 for (i=n;i>=num[l];i--)
	  for (j=m;j>=tl[l];j--)
	    f[i][j]=max(f[i][j],f[i-num[l]][j-tl[l]]+1);
	if (f[n][m]==0)
	  {printf("0 %d",m); return 0;}
	int a1,a2;
	a1=a2=0;
	for (i=1;i<=n;i++)
	 for (j=1;j<=m;j++)
	  if (f[i][j]>a1||f[i][j]==a1&&m-j>a2)
	    {a1=f[i][j]; a2=m-j;}
	printf("%d %d",f[n][m],a2);
	return 0;
}


#include<cstdio>
#include<cstring>
using namespace std;
int f[25],d=1,x=1,b=1,n;
int main()
{
	int i;
	scanf("%d",&n);
	f[1]=3;
	for (i=2;i<=n;i++)
	 {
	  int t=0;
	  f[i]+=d*2+b*3+x*2;
	  t=d+b+x; d+=b; x+=b; b=t;
	 }
	printf("%d",f[n]);
	return 0;
}
【奇怪递推方法开心水过~】


#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int f[1000010],a[110],v[110],t,n,k;
void do1(int m,int b,int j)
{
	int x;
	x=max(m+k,a[j]-1);
	for (int i=m+1;i<=x;i++)
	  f[i]=b;
	return;
}
int main()
{
	int i,j,l;
	scanf("%d",&t);
	for (l=1;l<=t;l++)
	 {
	  int x;
	  memset(f,0,sizeof(f));
	  memset(a,0,sizeof(a));
	  scanf("%d%d",&n,&k);
	  for (i=1;i<=n;i++)
	   scanf("%d",&a[i]);
	  for (i=1;i<=n;i++)
	   scanf("%d",&v[i]);
	  do1(a[1],v[1],2);
	  f[a[1]]=v[1];
	  for (i=2;i<=n;i++)
	   {
	   	for (j=max(a[i]-k,1);j<a[i];j++)
	   	 f[a[i]]=max(f[a[i]],f[j]);
	   	f[a[i]]=max(f[max(a[i]-k-1,0)]+v[i],f[a[i]]);
	   	if (i!=n)
		 do1(a[i],f[a[i]],i+1);
	   }
	  printf("%d\n",f[a[n]]);
	 }
	return 0;
 } 


#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int f[10010],w[5]={0,10,20,50,100},n;
int main()
{
	int i,j;
	scanf("%d",&n);
	if (n==0)
	   {printf("0"); return 0;} 
	if ((n%10!=0))
	   {printf("0"); return 0;}
	f[0]=1;
	for (i=1;i<=4;i++)
	 for (j=w[i];j<=n;j++)
	   f[j]+=f[j-w[i]];
    printf("%d",f[n]);
} 

#include<cstdio>
#include<cstring>
using namespace std;
int f[15][15],n,m,t;
int main()
{
	int i,j,k;
	scanf("%d",&t);
	for (k=1;k<=t;k++)
	 {
	  scanf("%d%d",&n,&m);
	  f[0][0]=1;
	  for (i=1;i<=n;i++)
	   for (j=1;j<=m;j++)
	     if (i>=j)
	       f[i][j]=f[i-1][j-1]+f[i-j][j];
	  for (i=1;i<m;i++)
	    f[n][m]+=f[n][i];
	  printf("%d\n",f[n][m]);
	  memset(f,0,sizeof(0));
	 }
} 


#include<cstdio>
#include<cstring>
#include<algorithm> 
using namespace std;
int a[110][110],f[110][110],n;
int main()
{
	int i,j;
	scanf("%d",&n);
	for (i=1;i<=n;i++)
	 for (j=1;j<=n;j++)
	  scanf("%d",&a[i][j]);
	memset(f,127/3,sizeof(f));
	f[1][1]=a[1][1];
	f[1][2]=f[1][1]+a[1][2];
	f[2][1]=f[1][1]+a[2][1];
	for (i=1;i<=n;i++)
	  for (j=1;j<=n;j++)
	    {
	     int sum;
	     sum=min(f[i][j-1],f[i-1][j])+a[i][j];
	     f[i][j]=min(f[i][j],sum);
	    }
	printf("%d",f[n][n]);
	return 0;
}


#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
int dis[610],f[510][510],last[510][510],n,m;
int main()
{
	int i,j,k;
	scanf("%d%d",&n,&m);
	memset(f,127,sizeof(f));
	memset(last,0,sizeof(last));
	for (i=2;i<=n;i++)
	 {
	  int x;
	  scanf("%d",&x);
	  dis[i]=dis[i-1]+x;
	 }
    for (i=1;i<=n;i++)
     for (j=i;j<=n;j++)
       {
       	int mid;
       	mid=(i+j)>>1;
       	for (k=i;k<=j;k++)
       	  last[i][j]+=abs(dis[k]-dis[mid]);
       }
   for (i=1;i<=n;i++)
     f[1][i]=last[1][i];
   for (i=2;i<=m;i++)
    for (j=i;j<=n;j++)
      for (k=i-1;k<j;k++)
        f[i][j]=min(f[i][j],f[i-1][k]+last[k+1][j]);
   printf("%d",f[m][n]);
   return 0; 
}



#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int f[110][20],n,m;//f[i][j]表示i层楼,j个鸡蛋 
int main()
{
	int i,j,k;
	while ((scanf("%d%d",&n,&m)==2)&&n!=0&&m!=0)
	 {
	  memset(f,0,sizeof(f));
	  for (i=1;i<=n;i++)
	    f[i][1]=i;//如果只有一个鸡蛋,那么它只能从第一层开始扔,最坏情况为i次 
	  for (i=1;i<=n;i++)
	   for (j=2;j<=m;j++)
	    {
	  	 f[i][j]=max(f[i-1][j-1],f[i+1][j])+1;//从在i层楼扔j个鸡蛋碎了的情况和没碎的情况中选择一个最优的(因为是最坏情况,所以要找最大的),并加上当前扔的这一次作为f[i][j]的初值 
	  	 for (k=2;k<=i;k++)
	  	   f[i][j]=min(f[i][j],max(f[k-1][j-1],f[i-k][j])+1);//从第1层到第i层向下扔中选择最优值(分碎和没碎两种情况)并加上当前这种情况,与f[i][j]的初值相比,选最优的(因为是最坏情况的最优策略,所以要找最小值) 
	    }
	  printf("%d\n",f[n][m]);
	 }
	return 0;
 } 
 //多组数据!!好吧,我又没仔细看题…… 


#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int f[100010],t,n,a[100010];
int main()
{
	int i,k;
	scanf("%d",&t);
	for (k=1;k<=t;k++)
	 {
	  memset(a,0,sizeof(a));
	  memset(f,0,sizeof(f));
	  scanf("%d",&n);
	  for (i=1;i<=n;i++)
	   scanf("%d",&a[i]);
	  f[1]=a[1]; f[2]=max(a[1],a[2]);
	  for (i=3;i<=n;i++)
	    {
	     f[i]=max(f[i-1],f[i-2]+a[i]);
	     f[i]=max(f[i-1],f[i]);
		 } 
	  printf("%d\n",f[n]);
	 } 
	
 } 



#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int f[100010],g[100010],n,a[100010];
int main()
{
	int i,j,k;
	scanf("%d",&n);
	for (k=1;k<=n;k++)
	 {
	  int t,m,ans=0;
	  scanf("%d",&t);
	  for (i=1;i<=t;i++)
	   scanf("%d",&a[i]);
	  m=a[1];
	  for (i=2;i<=t;i++)
	   {
	   	f[i]=a[i]-m;
	   	if (a[i]<m) m=a[i];
	   }
	  m=a[t];
	  for (i=t;i>0;i--)
	   {
	   	g[i]=m-a[i];
	   	if (a[i]>m) m=a[i];
	   }
	  for (i=2;i<=t;i++)
	    f[i]=max(f[i-1],f[i]);
	  for (i=t;i>1;i--)
	    g[i]=max(g[i],g[i-1]);
	  for (i=1;i<t;i++)
	   ans=max(f[i]+g[i+1],ans);
	  printf("%d\n",ans);
	 }
 } 


#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int f[20][20],n,m,t;
int main() 
{
	int i,j,k;
	f[0][0]=1;
	for (i=1;i<=10;i++)
	 for (j=1;j<=10;j++)
	  if (i>=j)
	    f[i][j]=f[i-1][j-1]+f[i-j][j];
	for (i=1;i<=10;i++)
	 for (j=1;j<=10;j++)
	   f[i][j]+=f[i][j-1];
    scanf("%d",&t);
    for (i=1;i<=t;i++)
     {
     	scanf("%d%d",&n,&m);
     	printf("%d\n",f[n][m]);
     }
    return 0;
}


#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
using namespace std;
int n,f[1010],l1;//f[i]表示前i-1位切了多少刀 
char a[1010];
bool check(int s,int l)//判断能否构成回文 
{
	while (s<=l)
	 if (a[s]==a[l])
	  {s++; l--; }
	  else return false;
	return true;
}
int main()
{
	int i,j,k;
	scanf("%d",&n);
	for (k=1;k<=n;k++)
	 {
	  cin>>a;
	  l1=strlen(a);
	  for (i=0;i<l1/2;i++)
	   if (a[i]!=a[l1-1-i])
	     break;
	  if (i==l1/2) 
	    {printf("0\n"); continue;}
	  f[0]=0; 
	  for (i=1;i<l1;i++)
	   f[i]=i;
	  for (i=1;i<l1;i++)
	   {
	   	if (check(0,i))//如果到当前位能构成一个回文,就不用切 
		   {f[i]=0; continue;} 
		for (j=0;j<i;j++)
	     if (check(j+1,i))//如果在j处切1刀,从j+1到i能构成回文,就可以切着一刀 
	      f[i]=min(f[j]+1,f[i]);
	   }//每次判断在j处切一刀,j+1到i能否构成回文 
	  printf("%d\n",f[l1-1]);
	 }
	return 0;
}//首次自己写出崭新的动归,好开森! 


#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int f[20010],v[50],n,m;
int main()
{
	int i,j;
	scanf("%d%d",&m,&n);
	for (i=1;i<=n;i++)
	 scanf("%d",&v[i]);
	for (i=1;i<=n;i++)
	 for (j=m;j>=v[i];j--)
	  if (f[j-v[i]]+v[i]<=m)
	   f[j]=max(f[j],f[j-v[i]]+v[i]);
	printf("%d",m-f[m]); 
	return 0;
	
}



#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int a[15][15],f[15][15][15][15],n;
int main()
{
	int i,j,l,k;
	int x,y,z;
	scanf("%d",&n);
	while (scanf("%d%d%d",&x,&y,&z)==3&&x!=0&&y!=0&&z!=0)
	  a[x][y]=z;
	for (i=1;i<=n;i++)
	 for (j=1;j<=n;j++)
	  for (l=1;l<=n;l++)
	   for (k=1;k<=n;k++)
	    if (i!=l&&j!=k) 
		 {
	      f[i][j][l][k]=max(f[i-1][j][l-1][k]+a[i][j]+a[l][k],f[i][j][l][k]);
	      f[i][j][l][k]=max(f[i-1][j][l][k-1]+a[i][j]+a[l][k],f[i][j][l][k]);
		  f[i][j][l][k]=max(f[i][j-1][l-1][k]+a[i][j]+a[l][k],f[i][j][l][k]);
		  f[i][j][l][k]=max(f[i][j-1][l][k-1]+a[i][j]+a[l][k],f[i][j][l][k]);	
		 }
		else
		  {
		  	f[i][j][l][k]=max(f[i-1][j][l-1][k]+a[i][j],f[i][j][l][k]);
	        f[i][j][l][k]=max(f[i-1][j][l][k-1]+a[i][j],f[i][j][l][k]);
		    f[i][j][l][k]=max(f[i][j-1][l-1][k]+a[i][j],f[i][j][l][k]);
		    f[i][j][l][k]=max(f[i][j-1][l][k-1]+a[i][j],f[i][j][l][k]);	
		  }
	printf("%d",f[n][n][n][n]);
	return 0;
}
(方格取数还有23进阶版。。。但不是用dp做了)



#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int f[210][20],n,k;
int main()
{
	int i,j;
	scanf("%d%d",&n,&k);
	f[0][0]=1;
	for (i=1;i<=n;i++)
	 for (j=1;j<=k;j++)
	   if (i>=j)
	     f[i][j]=f[i-j][j]+f[i-1][j-1];
	printf("%d",f[n][k]);
	return 0;
}//分情况,①不含一份为1的情况,就将i个1先分为j份,再将剩下的分为j份;②至少有一份为1的情况,将剩下的i-1个1分为j-1份; 



#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int r,c,a[110][110],f[110][110],ans,maxn=0;
int search(int x,int y)
{
	if (f[x][y]!=0) return f[x][y];
	if (x-1>0&&a[x-1][y]>a[x][y])
        f[x][y]=max(f[x][y],search(x-1,y)+1);
    if (x+1<=r&&a[x+1][y]>a[x][y])
        f[x][y]=max(f[x][y],search(x+1,y)+1);
    if (y-1>0&&a[x][y-1]>a[x][y])
        f[x][y]=max(f[x][y],search(x,y-1)+1);
    if (y+1<=c&&a[x][y+1]>a[x][y])
        f[x][y]=max(f[x][y],search(x,y+1)+1);
    return f[x][y];
}
int main()
{
	int i,j,n,m;
	scanf("%d%d",&r,&c);
	for (i=1;i<=r;i++)
	  for (j=1;j<=c;j++)
	    {
	     scanf("%d",&a[i][j]);
		}
	for (i=1;i<=r;i++)
	  for (j=1;j<=c;j++)
	    search(i,j);
	for (i=1;i<=r;i++)
	  for (j=1;j<=c;j++)
	    if (f[i][j]>maxn)
	       maxn=f[i][j];
	printf("%d",maxn+1);
	return 0;
}

[持续更新ing]

posted @ 2016-09-18 20:51  lris0-0  阅读(112)  评论(0编辑  收藏  举报
过去的终会化为美满的财富~o( =∩ω∩= )m