HDU - 1024
#include<iostream>
#include<cstdio>
#include<cstring>
#include<stack>
using namespace std;
#define pb(x) push_back(x)
#define sca(x) scanf("%d",&x)
#define inf 0x3f3f3f3f
#define LL long long
LL a[1000005];
LL mx[1000005];
LL dp[1000005];
int main()
{
int m,n;
while(~scanf("%d%d",&m,&n))
{
for(int i=1;i<=n;i++)scanf("%lld",&a[i]);
memset(dp,0,sizeof(dp));
memset(mx,0,sizeof(mx));
LL tmp=-inf;
for(int i=1;i<=m;i++)
{
tmp=-919999999999999999LL;
for(int j=i;j<=n;j++)
{
if(i==j)dp[j]=dp[j-1]+a[j];
else
dp[j]=max(dp[j-1],mx[j-1])+a[j];
mx[j-1]=tmp;
if(dp[j]>tmp)tmp=dp[j];
}
}
cout<<tmp<<endl;
}
}
/*
n个数中取出m段,要求m段的和最大。
每新加入一个数,要么自己独立成一段,要么跟前边那一个数
属于同一段。
所以dp[i][j]表示j个数分i段必须取j的最大值。
对于dp[i][j]=max(dp[i][j-1],max(dp[i-1][k])+a[j]) (k->[1,j-1]);
dp[i][j]的值依赖于dp[i][j-1]和dp[i-1][k];
可以用滚动数组。
其实dp[i-1][k]就是上一行1-(j-1)的最大值,我们可以用一个一维数组记录。
既mx数组。
这样dp数组也可以用一维的了。
*/
HDU - 1029
#include<iostream>
#include<cstdio>
#include<cstring>
#include<stack>
using namespace std;
#define pb(x) push_back(x)
#define sca(x) scanf("%d",&x)
#define inf 0x3f3f3f3f
#define LL long long
int main()
{
int n;
while(~scanf("%d",&n))
{
int sum=0;
int ans;
for(int i=1;i<=n;i++)
{
int tmp;
sca(tmp);
if(sum==0)
{
ans=tmp;
sum++;
}
else if(tmp==ans)
{
sum++;
}
else sum--;
}
printf("%d\n",ans);
}
}
/*
求出现次数为(n+1)/2次的数,n为奇数
1.排序,中中位数。
2.考虑不同数抵消。最后剩下的是要求的数。
*/
HDU - 1069
#include<iostream>
#include<cstdio>
#include<cstring>
#include<stack>
#include<algorithm>
using namespace std;
#define pb(x) push_back(x)
#define sca(x) scanf("%d",&x)
#define inf 0x3f3f3f3f
#define LL long long
struct node
{
int x,y,z;
friend bool operator <(node a,node b)
{
if(a.x!=b.x)return a.x<b.x;
else return a.y<b.y;
}
}a[100005];
int dp[10005];
int main()
{
int n;
int cas=1;
while(cin>>n&&n)
{
int cnt=1;
memset(dp,0,sizeof(dp));
for(int i=1;i<=n;i++)
{
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
a[cnt].x=x,a[cnt].y=y,a[cnt].z=z,cnt++;
a[cnt].x=x,a[cnt].y=z,a[cnt].z=y,cnt++;
a[cnt].x=y,a[cnt].y=x,a[cnt].z=z,cnt++;
a[cnt].x=y,a[cnt].y=z,a[cnt].z=x,cnt++;
a[cnt].x=z,a[cnt].y=x,a[cnt].z=y,cnt++;
a[cnt].x=z,a[cnt].y=y,a[cnt].z=x,cnt++;
}
sort(a+1,a+cnt);
int ans=-199;
for(int i=1;i<cnt;i++)dp[i]=a[i].z;
for(int i=1;i<cnt;i++)
{
for(int j=1;j<i;j++)
{
if(a[j].x<a[i].x&&a[j].y<a[i].y)
{
dp[i]=max(dp[i],dp[j]+a[i].z);
ans=max(ans,dp[i]);
}
}
}
printf("Case %d: maximum height = ",cas++);
cout<<ans<<endl;
}
}
/*
给了一维2微的x和y,一个高度
要求x和y都是严格递减的,求最大高度。其中每种方块都有无限个。
每个方块通过旋转最多产生6种方块。
对一维排序,对另一维求一个最长下降子序列。
如果要求每种块的最大高度就是cdq分治了。
*/
HDU - 1074
#include<iostream>
#include<cstdio>
#include<cstring>
#include<stack>
#include<algorithm>
using namespace std;
#define pb(x) push_back(x)
#define sca(x) scanf("%d",&x)
#define inf 0x3f3f3f3f
#define LL long long
string str[20];
int dead[20],cost[20];
int dp[1<<16];
int T[1<<16];
int pre[1<<16],name[1<<16];
int main()
{
int t;
cin>>t;
while(t--)
{
int n;
sca(n);
memset(dp,inf,sizeof(dp));
memset(T,0,sizeof(T));
for(int i=0;i<n;i++)
{
cin>>str[i]>>dead[i]>>cost[i];
}
int bit=1<<n;
T[0]=0;
dp[0]=0;
for(int i=1;i<bit;i++)
{
for(int j=n;j>=0;j--)
{
int tmp=1<<j;
if(!(i&tmp))continue;
int tmp1=i^tmp;
int red=max(T[tmp1]+cost[j]-dead[j],0);
int v=dp[tmp1]+red;
//cout<<i<<" "<<j<<" "<<v<<endl;
if(v<dp