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

来源:互联网 发布:js加密get请求路径 编辑:程序博客网 时间:2024/05/16 12:26

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;}
(方格取数还有2、3进阶版。。。但不是用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]

0 0
原创粉丝点击