10.11

来源:互联网 发布:win7 64位安装apache 编辑:程序博客网 时间:2024/06/03 17:41

造盒子

手动计算打表可得50分。

正解:由面积为5时橡皮泥的画法得到启示当边数为偶数时我们找一个最接近正方形的矩形使得总面积最大。当边数为奇数时,我们在比他小的一个偶数边的基础上,将最长边拆开,增加一条边使面积增大。

分玩具

dp[i]表示在还剩下最后i个数的情况下,先手比后手最多多多少愉快度(每一次拿到的最小值)。显然每个人每次拿走最大的几个数是最有策略的,所以把数字

从小到大排序,j代表先手,i代表后手,则dp[j]=max(a[i+1]-dp[i]}

#include<iostream>#include<cstdio>#include<cstring>#include<string>#include<cmath>#include<ctime>#include<algorithm>using namespace std;int a[1000010];long long f[1000010];int main(){//freopen("k.in","r",stdin);//freopen("k.out","w",stdout);ios::sync_with_stdio(false);cin.tie(NULL);int n;long long maxn;cin>>n;for(int i=1;i<=n;i++)cin>>a[i];sort(a+1,a+n+1);maxn=a[1];for(int i=1;i<=n;i++){f[i]=maxn;maxn=max(maxn,a[i+1]-f[i]);}cout<<f[n];return 0;}
problem
对于任意一串子序列[L,R],若a[i]之和>=(r-l+1)*k,则合法。所以进行a[i]-k操作使得前缀和s[R]-s[L]>=0,求出最大的R-L.(40分)
正解:求出关于a[i]的单调不增的栈s,然后从右向左扫描。
#include<iostream>#include<cstdio>#include<cstring>#include<string>#include<cmath>#include<ctime>#include<algorithm>using namespace std;long long a[1000010],s[1000010],t[1000010];int main(){//freopen("k.in","r",stdin);//freopen("k.out","w",stdout);ios::sync_with_stdio(false);cin.tie(NULL);int n,m,l,ans;long long k;cin>>n>>m;for(int i=1;i<=n;i++)cin>>a[i];for(int cas=1;cas<=m;cas++){memset(s,0,sizeof(s));memset(t,0,sizeof(t));ans=0;cin>>k;for(int i=1;i<=n;i++)        {    s[i]=s[i-1]+a[i]-k;    t[i]=min(t[i-1],s[i]);    }l=n-1;for(int i=n;i>=1;i--){if(i==l)l--;while(s[i]-t[l]>=0&&l>=0){l--;}ans=max(ans,i-l-1);}cout<<ans<<" ";}return 0;}