题意:
就是给你一个n(n<=100)的数组,这个数组是非下降的,然后定义这个数组的价值是所有(va[i]-va[i-1])2 。然后每次操作,你可以选择一个数删掉或者不删,然后再让其中一个数变成任意其他的数。但是不能操作第一个数和最后一个数。现在让你输出操作次数分别为[1,n]的答案。
思考:
- 当时看到这题,看到数组范围很小,感觉有点像区间dp,但是又有一个操作次数的限制,区间dp的话这都4维了,所以并不是。然后我又想感觉是思维?但是想了几个贪心并不对。然后就有点无语了,然后感觉周从开始都在看这个,应该可以写出来,但是也是卡住了。
- 其实这题,没更深入的思考,注意看要么是删去,要么是变成任意数,但是又不能动最两端的数,那么可以发现对于删掉和变成任意的数,这两种操作产生的贡献是一样的,因为删掉和变数都是产生左边和右边乘积的贡献。
- 所以这样就简单了,求最大值最小值,往往就是贪心,二分,dp。转化后发现贪心也不太好贪心,二分也不好处理,那么就dp。可以定义dp状态为dp[i][j]为第i个选择,并且用了j次操作的最大值。那么就可以三重循环去更新dp了。对于最后输出n个答案,就看看用了2×i次操作可以达到什么答案,由于操作n-2次就是最大值了,那么就是dp[n][min(i*2,n-2)]。由于转移的时候,至少是从1来转移的,所以1是必选的,而且dp[n]也是n必选的,所以就保证了答案的正确性。
- 说真的,比赛的时候,就要像平时做题一样,仔细思考,有时间去解决。对于任意一个题目,都不能把那种想把题目交给的队友的思想。因为有时候不同的思想对题目的解决很重要,有时候队友的思路被卡,就需要自己去解决。对于一个题目想不同的算法的时候,都要深入思考一下,真的是不是没有办法解决,而不是感觉没有就直接换算法。
代码:
#include<bits/stdc++.h>
#define fi first
#define se second
#define pb push_back
#define db double
#define int long long
#define PII pair<int,int >
#define mem(a,b) memset(a,b,sizeof(a))
#define IOS std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
using namespace std;
const int mod = 1e9+7,inf = 1e18;
const int N = 2e5+10,M = 2010;
int T,n,m,k;
int va[N];
int dp[M][M];
signed main()
{
IOS;
cin>>n;
for(int i=1;i<=n;i++) cin>>va[i];
for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) dp[i][j] = -inf;
int sum = 0;
for(int i=2;i<=n;i++) //这个初始化加不加都可,但是最好还是养成初始化的好习惯
{
sum += (va[i]-va[i-1])*(va[i]-va[i-1]);
dp[i][0] = sum;
}
for(int i=2;i<=n;i++)
{
for(int j=0;j<=n-2;j++)
{
for(int k=1;k<i;k++)
{
int res = i-k-1;
if(j>=res)
dp[i][j] = max(dp[i][j],dp[k][j-res]+(va[i]-va[k])*(va[i]-va[k]));
}
}
}
for(int i=1;i<=n;i++) cout<<dp[n][min(i*2,n-2)]<<"\n";
return 0;
}
题意:
思考:
代码:
#include<bits/stdc++.h>
#define fi first
#define se second
#define pb push_back
#define db double
#define int long long
#define PII pair<int,int >
#define mem(a,b) memset(a,b,sizeof(a))
#define IOS std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
using namespace std;
const int mod = 1e9+7,inf = 1e18;
const int N = 2e5+10,M = 2010;
int T,n,m,k;
int va[N];
signed main()
{
IOS;
cin>>n;
for(int i=1;i<=n;i++) cin>>va[i];
int t1 = 0,t2 = 0;
for(int i=1;i<=n;i++)
{
if(va[i]>va[i-1]) t1++;
else break;
}
for(int i=n;i>=1;i--)
{
if(va[i]>va[i+1]) t2++;
else break;
}
if(t1%2!=0||t2%2!=0) cout<<"Alice";
else cout<<"Bob";
return 0;
}
题意:
思考:
代码:
题意:
思考:
代码:
题意:
思考:
代码: