由于是写个自己看的,题意就不放了
ProblemA
思路:
存数的数组 a[maxn]
先建立二维数组 dp[i][j] 含义:前j个数分i组所得最大值
在第j个数这,其选取有两种情况:(每种情况必须满足选后组份为i)
case 1 :已经有了i-1组 slove:将a[j]作为单独一组加入 ---->dp[i][j]=max(dp[i-1][k])+a[j] i-1<=k<=j-1
case 2 :已经有了i组 slove:将a[j]添加到前i组中的某一组 又由于区间连续性 因此只能添加到含有a[j-1]的那组 dp[i][j]=dp[i][j-1]+a[i]
综上 状态转移方程: dp[i][j]=max(dp[i][j-1],max(dp[i-1][k]))+a[j] i-1<=k<=j-1其中max(dp[i-1][k])可以用一数组记录
那么二维dp数组解的代码:
/*********************************************************************/
/**********************************cyf*******************************/
/*******************************************************************/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define rep(i,x) for(int i=0;i
#define ll long long
#define repp(i,x) for(int i=1;i<=x;i++)
#define repx(i,n,j) for(int i=j;i
#define rep(i,begin,end) for(int i=begin;i<=end;i++)
#define mst(a,b) memset(a,b,sizeof(a))
#define drep(i,a,b) for(int i=a;i>=b;i--)
const ll mod=1e9+7;
const int INF=0x3f3f3f3f;;
const int maxn=1e4+5;
ll a[maxn],dp[maxn][maxn],zj[maxn][maxn];
int main()
{
int n,m;
ll ans;
while(cin>>m>>n)
{
rep(i,1,n)
cin>>a[i];
mst(dp,0);
mst(zj,0);
rep(i,1,m)
{
ans=-INF;
rep(j,i,n)
{
dp[i][j]=max(dp[i][j-1],zj[i-1][j-1])+a[j];
if(j>=i)
zj[i][j]=max(zj[i][max(i,j-1)],dp[i][j]);
if(i==m)
ans=max(dp[m][j],ans);
}
}
cout<<ans<<endl;
}
return 0;
}
但是你的编译器会给你报错 数组开太大 因此我们要用滚动数组优化
/*********************************************************************/
/**********************************cyf*******************************/
/*******************************************************************/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define rep(i,x) for(int i=0;i
#define ll long long
#define repp(i,x) for(int i=1;i<=x;i++)
#define repx(i,n,j) for(int i=j;i
#define rep(i,begin,end) for(int i=begin;i<=end;i++)
#define mst(a,b) memset(a,b,sizeof(a))
#define drep(i,a,b) for(int i=a;i>=b;i--)
const ll mod=1e9+7;
const int INF=0x3f3f3f3f;;
const int maxn=1e6+5;
ll a[maxn];
ll dp[maxn];
ll zj[maxn];
int main()
{
int n,m;
ll ans;
while (~scanf("%d %d",&m,&n))
{
rep(i,1,n)
scanf("%lld",&a[i]);
mst(dp,0);
mst(zj,0);
rep(i,1,m)
{
ans=-INF;
rep(j,i,n)
{
dp[j]=max(dp[j-1]+a[j],zj[j-1]+a[j]);
zj[j-1]=ans;
ans=max(ans,dp[j]);
}
}
printf("%lld\n",ans);
}
return 0;
}
pronlemB
这题感觉不是dp题,可能是我理解不够
一种O(n)写法:
可知至少出现(n+1)/2次,那么出现次数>数据的一半
定义一个计数变量 unt
case 1 unt==0 : unt=1 ans=a[i]
case 2 unt!=0: ans和a[i]比较 同unt++,不同unt–
/*********************************************************************/
/**********************************cyf*******************************/
/*******************************************************************/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define rep(i,x) for(int i=0;i
#define ll long long
#define repp(i,x) for(int i=1;i<=x;i++)
#define repx(i,n,j) for(int i=j;i
#define rep(i,begin,end) for(int i=begin;i<=end;i++)
#define mst(a,b) memset(a,b,sizeof(a))
#define drep(i,a,b) for(int i=a;i>=b;i--)
const ll mod=1e9+7;
const int INF=0x3f3f3f3f;;
const int maxn=1e6+5;
ll a[maxn];
ll dp[maxn];
ll zj[maxn];
int main()
{
ll n;
ll ans,unt,x;
while (~scanf("%lld",&n))
{
unt=0;
rep(i,1,n)
{
scanf("%lld",&x);
if(unt==0)
{
unt++;
ans=x;
}
else
{
if(ans==x)
unt++;
else
{
unt--;
}
}
}
printf("%lld\n",ans);
}
return 0;
}
problemC
这题因为码的时候一个手误差点把我人wa没了
最长递增子序列O(n^2)解法 另一种还没学
解法:
每一种石头长宽高按全排 最终共6*n总
长宽sort一遍
dp[i]就是以i快石头结尾最大高度
dp[i]=max(a[i].g,dp[k]) 这里1<=k<=i-1 && a[k]满足题目条件
结果就是dp数组最大值
(注释是dbug留下的产物)
/*********************************************************************/
/**********************************cyf*******************************/
/*******************************************************************/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define rep(i,x) for(int i=0;i
#define ll long long
#define repp(i,x) for(int i=1;i<=x;i++)
#define repx(i,n,j) for(int i=j;i
#define rep(i,begin,end) for(int i=begin;i<=end;i++)
#define mst(a,b) memset(a,b,sizeof(a))
#define drep(i,a,b) for(int i=a;i>=b;i--)
const ll mod=1e9+7;
const int INF=0x3f3f3f3f;;
const int maxn=1e3+5;
struct st
{
ll c,k,g;
}a[maxn];
bool ccmmpp(struct st x,struct st y)
{
if(x.c==y.c)
{
return x.k>y.k;
}
return x.c>y.c;
}
ll dp[maxn];
int main()
{
int tt=0;
ll n,ans;
ll x,y,z,js=1;
while(cin>>n && n!=0){
tt++;
js=1;
rep(i,1,n)
{
cin>>x>>y>>z;
a[js].c=x;
a[js].k=y;
a[js++].g=z;
a[js].c=x;
a[js].k=z;
a[js++].g=y;
a[js].c=y;
a[js].k=x;
a[js++].g=z;
a[js].c=y;
a[js].k=z;
a[js++].g=x;
a[js].c=z;
a[js].k=x;
a[js++].g=y;
a[js].c=z;
a[js].k=y;
a[js++].g=x;
}
js--;
/*cout<
n=js;
/*rep(i,1,n)
cout<
ans=0;
mst(dp,0);
sort(a+1,a+1+n,ccmmpp);
rep(i,1,n)
{
/*cout<
ll t=0;
rep(j,1,i-1)
{
/*cout<
if(a[j].c>a[i].c && a[j].k>a[i].k)
t=max(t,dp[j]);
}
/*cout<
dp[i]=t+a[i].g;
/*cout<
ans=max(ans,dp[i]);
}
/*cout<
printf("Case %d: maximum height = %lld\n",tt,ans);
/*cout<<"Case "<}
return 0;
}