您的位置:首页 > 产品设计 > UI/UE

2014 UESTC Training for Dynamic Programming

2014-06-02 12:00 549 查看
2ms 二维背包的解法
dp[i][VA][VB]表示考虑前i个数,当前A集合的异或和为VA,B集合的异或和为VB
转移:因为A&B=0,所以ai要么加到A集合中,要么加到B集合中,要么都不加

要求是输出集合A异或和小于集合B异或和方案书目
那么答案就是dp
[i][j](i<=j)每次循环到127(二进制对应111111可能出现的最大的异或和)
空集视为一组解 那么dp[0][0][0]=1初始化
接下来只需要不断更新DP[i][j][k]即可最终输出答案
dp[i][j^src[i]][k]+=dp[i-1][j][k];
                   dp[i][j][k^src[i]]+=dp[i-1][j][k];
                   dp[i][j][k]+=dp[i-1][j][k];
#include <map>#include <set>#include <list>#include <cmath>#include<cctype>#include <ctime>#include <deque>#include <stack>#include <queue>#include <cstdio>#include <string>#include <vector>#include <cstdlib>#include <cstring>#include <iostream>#include <algorithm>#define LL long long#define PI 3.1415926535897932626using namespace std;int gcd(int a, int b){return a % b == 0 ? b : gcd(b, a % b);}int dp[20][130][130];int N;bool vis[20][130][130];int src[20];int main(){while (scanf("%d",&N)!=EOF){int max=-1;memset(vis,false,sizeof(vis));memset(dp,0,sizeof(dp));for (int i=1;i<=N;i++){scanf("%d",&src[i]);}//for (int i=0;i<=N;i++)dp[i][0][0]=1;dp[0][0][0]=1;for (int i=1;i<=N;i++){for (int j=0;j<=128;j++)for (int  k=0;k<=128;k++){dp[i][j^src[i]][k]+=dp[i-1][j][k];dp[i][j][k^src[i]]+=dp[i-1][j][k];dp[i][j][k]+=dp[i-1][j][k];}}int ans=0;for (int i=0;i<=128;i++)for (int j=i;j<=128;j++)ans+=dp[i][j];printf("%d\n",ans);}return 0;}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: