简介:
沙漏型的三角形取数,输出方案数
分析:
S的范围很小,这就提醒我们可以枚举
于是我在朴素的三角形取数的状态上又加一维
f[s][i][j] 表示到(i,j)这个点,和是s的方案数
注意
倒三角中,f[i][j]从f[i+1][j]和f[i+1][j-1]转移
正三角中,f[i][j]从f[i+1][j]和f[i+1][j+1]转移
方案的输出:
我们直接迭代
for (int i=1;i<n;i++)
{
S-=a[i][x];
if (f[S][i+1][x-1]) cout<<'L',x--;
else cout<<'R';
}
for (int i=n;i<2*n-1;i++)
{
S-=a[i][x];
if (f[S][i+1][x]) cout<<'L';
else cout<<'R',x++;
}
tip
状态的转移一定要好好分析
循环的时候,数组下标一定不要出现负数
开ll
//这里写代码片
#include<cstdio>
#include<cstring>
#include<iostream>
#define ll long long
using namespace std;
ll f[503][45][25];
int a[45][25];
int n,S;
void doit()
{
int i,j,k;
memset(f,0,sizeof(f));
for (int i=1;i<=n;i++) f[a[2*n-1][i]][2*n-1][i]=1;
for (i=2*n-2;i>=n;i--)
for (j=1;j<=i-n+1;j++)
for (k=a[i][j];k<=S;k++)
{
f[k][i][j]+=f[k-a[i][j]][i+1][j];
f[k][i][j]+=f[k-a[i][j]][i+1][j+1];
}
for (i=n-1;i>=1;i--)
for (j=1;j<=n-i+1;j++)
for (k=a[i][j];k<=S;k++)
{
f[k][i][j]+=f[k-a[i][j]][i+1][j];
f[k][i][j]+=f[k-a[i][j]][i+1][j-1];
}
}
int main()
{
while (scanf("%d%d",&n,&S)!=EOF&&n)
{
memset(a,0,sizeof(a));
memset(f,0,sizeof(f));
for (int i=1;i<=n;i++)
for (int j=1;j<=n-i+1;j++)
scanf("%d",&a[i][j]);
for (int i=n+1;i<=2*n-1;i++)
for (int j=1;j<=i-n+1;j++)
scanf("%d",&a[i][j]);
doit();
ll ans=0;
int x=-1;
for (int i=1;i<=n;i++)
{
ans+=f[S][1][i];
if (f[S][1][i]&&x==-1) x=i;
}
printf("%lld\n",ans);
if (ans==0)
{
printf("\n");
continue;
}
printf("%d ",x-1);
for (int i=1;i<n;i++)
{
S-=a[i][x];
if (f[S][i+1][x-1]) cout<<'L',x--;
else cout<<'R';
}
for (int i=n;i<2*n-1;i++)
{
S-=a[i][x];
if (f[S][i+1][x]) cout<<'L';
else cout<<'R',x++;
}
printf("\n");
}
return 0;
}