题意:给十种秤砣,重量为1~10,个数无限,给n,问能否进行n次左右交替摆放秤砣,
满足以下规则:
每次放下一个秤砣后,该边重量必须大于另一边
并且这次放下的秤砣不能和上一次放下的秤砣种类相同。。。
这题居然爆搜也能过。估计是可行的答案分支比较多。。。
DP【k】【i】【j】表示 第k次摆放时,所选择摆放的那一边比另一边 重 i ,并且第k次选择的是重量为j的秤砣
初始化 for (i=1;i<=10;i++)
{
if (!vis[i]) continue;
dp[1][i][i]=1;
}
for (k=2;k<=n;k++)
{
for (i=1;i<=10;i++)
{
for (j=i;j<=10;j++)
{
if (!vis[j]) continue;
if (dp[k-1][i][j])<span style="white-space:pre"> </span>//如果上一次该情况存在
{
for (h=i+1;h<=10;h++)//看第k次能放哪个
{
if (!vis[h]) continue;<span style="white-space:pre"> </span>//存在
if (h==j) continue;<span style="white-space:pre"> </span>//不能与上一次相同
dp[k][h-i][h]=1;
out[k][h-i][h]=j;<span style="white-space:pre"> </span>//记录上一个秤砣的重量,一会回溯打印
}
}
}
}
}
DP:
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <queue>
#include <map>
#include <set>
#include <vector>
#include <iostream>
using namespace std;
const double pi=acos(-1.0);
double eps=0.000001;
int n;
int vis[15];
char str[15];
int dp[1005][15][15];
int ans[1005];
int ok=0;
int out[1005][15][15];
void print(int k,int i,int j)
{
if (k!=1)
print(k-1,j-i,out[k][i][j]);
printf("%d ",j);
}
int main()
{
int i,j,k,h;
scanf("%s",str+1);
for (i=1;i<=10;i++)
{
if (str[i]=='1')
vis[i]=1;
}
cin>>n;
for (i=1;i<=10;i++)
{
if (!vis[i]) continue;
dp[1][i][i]=1;
}
for (k=2;k<=n;k++)
{
for (i=1;i<=10;i++)
{
for (j=i;j<=10;j++)
{
if (!vis[j]) continue;
if (dp[k-1][i][j])
{
for (h=i+1;h<=10;h++)
{
if (!vis[h]) continue;
if (h==j) continue;
dp[k][h-i][h]=1;
out[k][h-i][h]=j;
}
}
}
}
}
for (i=1;i<=10;i++)
{
for (j=1;j<=10;j++)
{
if (dp[n][i][j])
{
printf("YES\n");
print(n,i,j);
printf("\n");
return 0;
}
}
}
printf("NO\n");
return 0;
}
爆搜:
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <queue>
#include <map>
#include <set>
#include <vector>
#include <iostream>
using namespace std;
const double pi=acos(-1.0);
double eps=0.000001;
int n;
int vis[15];
char str[15];
int ans[1005];
int ok=0;
int l=0;
int r=0;
int last=0;
int dfs( int compare,int cun)
{
if (cun==n+1) return 1;
int tmp=last;
for (int i=1;i<=10;i++)
{
if (!vis[i]) continue;
if (last!=i&& i>compare)
{
last=i;
if (dfs(i-compare,cun+1))
{
ans[cun]=i;
return 1;
}
last=tmp;
}
}
return 0;
}
int main()
{
scanf("%s",str+1);
int i;
for (i=1;i<=10;i++)
{
if (str[i]=='1')
vis[i]=1;
}
cin>>n;
if (dfs(0,1))
{
printf("YES\n");
for (i=1;i<=n;i++)
{
printf("%d ",ans[i]);
}
printf("\n");
}
else
printf("NO\n");
return 0;
}