1006-Cute Tree
题目大意
根据所给代码 输入一个n 问您最后生成多少个点
题目思路
记忆化搜索
当len=1 时return 当 len=2时生成两个 len=3时生成三个 当len>2时根据他所给公式计算分段
最后别忘了加上自身这个节点 还有分三段的第一段要注意向上取整
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=2e5+10;
int t,n;
ll dp[maxn];
ll dfs(int x)
{
if(dp[x])return dp[x];
if(x==3)return dp[3]=4;
if(x==2)return dp[2]=3;
if(x==1)return dp[1]=1;
ll ans=0;
if(x>3)
{
ll tt= (x-1)/3+1;
ans+=dfs(tt)+dfs((x-tt)/2)+dfs(x-(tt)-(x-tt)/2);
}
return dp[x]=ans+1;
}
int main()
{
cin>>t;
while(t--)
{
cin>>n;
ll ans=dfs(n);
int x;
while(n--)scanf("%d",&x);
cout<<ans<<endl;
}
//cout<<dp[3]<<endl;
//int qq=(10-1)/3+1;
//cout<<(10-qq)/2<<" "<<10-(qq)-(10-(qq/2))<<endl;
return 0;
}
1007-Banzhuan
题目大意
一个nxnxn的立方体 你要用1x1x1的方块去填他 方块放在(x,y,z)的代价为 v=x*y2*z
你需要让你填的这个物体 从上面 左面 前面看都是nxn的正方形 另外放置方案会保证万有引力
即你放在最上面 下面要是没有东西就会落下来 你要输出满足方案的最大值和最小值
题目思路
对于最小值来说 最下面的一层即z=1是一定会铺满的 因为满足地心引力 且只有铺满才能从上面看 满足nxn正方形 然后只需要考虑如何从左面和从前面看满足nxn
我一开始想的是既然代价是x*y2 那么肯定要让y最大时x最小 而且对于每一层来说 这一层的每一行每一列只需要出现一个方块即可 那么对于每一层可以这样放置
wa了两发后发现这样根本不是最优!
经思考发现 下面这个才是最优
因此最min的费用就是 最底下一层铺满 和 2-n层如上图放置
表达式为:
minans=左边的一面 + 前面的一面 + 最底下的一层
结合公式 1^2+2^2+3^2+…+n^2=n(n+1)(2n+1)/6
最后推出式子大概是(没化简)
然后考虑max费用 这里有一个坑 就是大多数人会默认觉得 直接全铺满nxnxn个格子 但实际上 由于满足万有引力 正确答案是从z=n这一层开始放 放n次 这样才是最大 费用!
则maxans=最上面一层 x n
#include<bits/stdc++.h>
#define debug(a,b) printf("%s = %d\n",a,b);
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
const ll INF_ll=1e18;
const int INF_int=0x3f3f3f3f;
inline ll read(){
ll s=0,w=1ll;
char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')w=-1ll;ch=getchar();}
while(ch>='0'&&ch<='9') s=s*10ll+((ch-'0')*1ll),ch=getchar();//s=(s<<3)+(s<<1)+(ch^48);
return s*w;
}
const int mod=1e9+7;
void rd_txt(){
#ifdef ONLINE_JUDGE
#else
freopen("in.txt","r",stdin);
#endif
}
ll qpow(ll a,ll b)
{
ll res = 1;
while(b)
{
if(b&1) res = res*a%mod;
a = a*a%mod;
b >>= 1;
}
return res;
}
void solve(){
ll n;
ll ans=0,sum=0;
scanf("%lld",&n);
n=n%mod;
ll t1=(((((((n*(n+1)%mod)*(2*n+1)%mod)%mod)*(qpow(6,mod-2)%mod)%mod))*(((1+n)*n)%mod-1+mod)%mod)%mod)%mod;
t1=(t1+2)%mod;
ll t2=(((n*(n+1))%mod )*((n*(n+1))%mod))%mod;
t2=(t2*(qpow(4,mod-2)%mod))%mod;
t2%=mod;
ll t3=(((3*(1+n)%mod*n)%mod)*(qpow(2,mod-2))%mod)%mod;
ans=(mod+t1+t2-t3)%mod;//最小值
cout<<ans<<endl;
ans=(((n*(n+1))%mod*((2*n+1)%mod))%mod*(qpow(6,mod-2))%mod)%mod;
sum=((((((((ans*n)%mod*(n+1))%mod)*qpow(2,mod-2)%mod)%mod)*n)%mod)*n)%mod;
printf("%lld\n",sum);//最大值
}
int main()
{
//rd_txt();
int t;
cin>>t;
while(t--){
solve();
}
}
//1000000000000000000