题意:给十种秤砣,重量为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; }